Skip to content

Commit eb421f6

Browse files
author
Huanxuan Ao
committed
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
1 parent 48ffd8c commit eb421f6

2 files changed

Lines changed: 76 additions & 9 deletions

File tree

openstackclient/network/v2/port.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,23 @@ def get_parser(self, prog_name):
284284

285285
def take_action(self, parsed_args):
286286
client = self.app.client_manager.network
287+
result = 0
287288

288289
for port in parsed_args.port:
289-
res = client.find_port(port)
290-
client.delete_port(res)
290+
try:
291+
obj = client.find_port(port, ignore_missing=False)
292+
client.delete_port(obj)
293+
except Exception as e:
294+
result += 1
295+
self.app.log.error(_("Failed to delete port with "
296+
"name or ID '%(port)s': %(e)s")
297+
% {'port': port, 'e': e})
298+
299+
if result > 0:
300+
total = len(parsed_args.port)
301+
msg = (_("%(result)s of %(total)s ports failed "
302+
"to delete.") % {'result': result, 'total': total})
303+
raise exceptions.CommandError(msg)
291304

292305

293306
class ListPort(command.Lister):

openstackclient/tests/network/v2/test_port.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
import mock
1515

16+
from mock import call
17+
from openstackclient.common import exceptions
1618
from openstackclient.common import utils
1719
from openstackclient.network.v2 import port
1820
from openstackclient.tests.network.v2 import fakes as network_fakes
@@ -174,30 +176,82 @@ def test_create_full_options(self):
174176

175177
class TestDeletePort(TestPort):
176178

177-
# The port to delete.
178-
_port = network_fakes.FakePort.create_one_port()
179+
# Ports to delete.
180+
_ports = network_fakes.FakePort.create_ports(count=2)
179181

180182
def setUp(self):
181183
super(TestDeletePort, self).setUp()
182184

183185
self.network.delete_port = mock.Mock(return_value=None)
184-
self.network.find_port = mock.Mock(return_value=self._port)
186+
self.network.find_port = network_fakes.FakePort.get_ports(
187+
ports=self._ports)
185188
# Get the command object to test
186189
self.cmd = port.DeletePort(self.app, self.namespace)
187190

188-
def test_delete(self):
191+
def test_port_delete(self):
189192
arglist = [
190-
self._port.name,
193+
self._ports[0].name,
191194
]
192195
verifylist = [
193-
('port', [self._port.name]),
196+
('port', [self._ports[0].name]),
194197
]
195198
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
196199

197200
result = self.cmd.take_action(parsed_args)
198-
self.network.delete_port.assert_called_once_with(self._port)
201+
self.network.find_port.assert_called_once_with(
202+
self._ports[0].name, ignore_missing=False)
203+
self.network.delete_port.assert_called_once_with(self._ports[0])
199204
self.assertIsNone(result)
200205

206+
def test_multi_ports_delete(self):
207+
arglist = []
208+
verifylist = []
209+
210+
for p in self._ports:
211+
arglist.append(p.name)
212+
verifylist = [
213+
('port', arglist),
214+
]
215+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
216+
217+
result = self.cmd.take_action(parsed_args)
218+
219+
calls = []
220+
for p in self._ports:
221+
calls.append(call(p))
222+
self.network.delete_port.assert_has_calls(calls)
223+
self.assertIsNone(result)
224+
225+
def test_multi_ports_delete_with_exception(self):
226+
arglist = [
227+
self._ports[0].name,
228+
'unexist_port',
229+
]
230+
verifylist = [
231+
('port',
232+
[self._ports[0].name, 'unexist_port']),
233+
]
234+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
235+
236+
find_mock_result = [self._ports[0], exceptions.CommandError]
237+
self.network.find_port = (
238+
mock.MagicMock(side_effect=find_mock_result)
239+
)
240+
241+
try:
242+
self.cmd.take_action(parsed_args)
243+
self.fail('CommandError should be raised.')
244+
except exceptions.CommandError as e:
245+
self.assertEqual('1 of 2 ports failed to delete.', str(e))
246+
247+
self.network.find_port.assert_any_call(
248+
self._ports[0].name, ignore_missing=False)
249+
self.network.find_port.assert_any_call(
250+
'unexist_port', ignore_missing=False)
251+
self.network.delete_port.assert_called_once_with(
252+
self._ports[0]
253+
)
254+
201255

202256
class TestListPort(TestPort):
203257

0 commit comments

Comments
 (0)