Support image deletion in batches in v2

Client doesn't support image deletion in batches in v2 now.
It's useful. So it's need to add it.

Change-Id: Idf5a6890b3fd01a65fecab2033b21367c30bc6b1
Closes-bug:#1485407
This commit is contained in:
wangxiyuan 2015-08-17 10:34:22 +08:00
parent d90c7d6896
commit bf02b048bf
3 changed files with 63 additions and 17 deletions

View File

@ -286,6 +286,10 @@ def exit(msg='', exit_code=1):
sys.exit(exit_code)
def print_err(msg):
print(encodeutils.safe_decode(msg), file=sys.stderr)
def save_image(data, path):
"""Save an image to the specified path.

View File

@ -13,6 +13,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import json
import mock
import os
@ -106,13 +107,15 @@ class ShellV2Test(testtools.TestCase):
utils.print_dict = mock.Mock()
utils.save_image = mock.Mock()
def assert_exits_with_msg(self, func, func_args, err_msg):
def assert_exits_with_msg(self, func, func_args, err_msg=None):
with mock.patch.object(utils, 'exit') as mocked_utils_exit:
mocked_utils_exit.return_value = '%s' % err_msg
func(self.gc, func_args)
mocked_utils_exit.assert_called_once_with(err_msg)
if err_msg:
mocked_utils_exit.assert_called_once_with(err_msg)
else:
mocked_utils_exit.assert_called_once_with()
def _run_command(self, cmd):
self.shell.main(cmd.split())
@ -591,24 +594,49 @@ class ShellV2Test(testtools.TestCase):
mocked_data.assert_called_once_with('IMG-01')
def test_do_image_delete(self):
args = self._make_args({'id': 'pass', 'file': 'test'})
args = argparse.Namespace(id=['image1', 'image2'])
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
mocked_delete.return_value = 0
test_shell.do_image_delete(self.gc, args)
self.assertEqual(2, mocked_delete.call_count)
mocked_delete.assert_called_once_with('pass')
@mock.patch.object(utils, 'exit')
@mock.patch.object(utils, 'print_err')
def test_do_image_delete_with_invalid_ids(self, mocked_print_err,
mocked_utils_exit):
args = argparse.Namespace(id=['image1', 'image2'])
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
mocked_delete.side_effect = exc.HTTPNotFound
test_shell.do_image_delete(self.gc, args)
self.assertEqual(2, mocked_delete.call_count)
self.assertEqual(2, mocked_print_err.call_count)
mocked_utils_exit.assert_called_once_with()
@mock.patch.object(utils, 'exit')
@mock.patch.object(utils, 'print_err')
def test_do_image_delete_with_forbidden_ids(self, mocked_print_err,
mocked_utils_exit):
args = argparse.Namespace(id=['image1', 'image2'])
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
mocked_delete.side_effect = exc.HTTPForbidden
test_shell.do_image_delete(self.gc, args)
self.assertEqual(2, mocked_delete.call_count)
self.assertEqual(2, mocked_print_err.call_count)
mocked_utils_exit.assert_called_once_with()
def test_do_image_delete_deleted(self):
image_id = 'deleted-img'
args = self._make_args({'id': image_id})
with mock.patch.object(self.gc.images, 'delete') as mocked_get:
mocked_get.side_effect = exc.HTTPNotFound
args = argparse.Namespace(id=[image_id])
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
mocked_delete.side_effect = exc.HTTPNotFound
msg = "No image with an ID of '%s' exists." % image_id
self.assert_exits_with_msg(func=test_shell.do_image_delete,
func_args=args,
err_msg=msg)
func_args=args)
def test_do_member_list(self):
args = self._make_args({'image_id': 'IMG-01'})

View File

@ -311,14 +311,28 @@ def do_image_upload(gc, args):
gc.images.upload(args.id, image_data, args.size)
@utils.arg('id', metavar='<IMAGE_ID>', help='ID of image to delete.')
@utils.arg('id', metavar='<IMAGE_ID>', nargs='+',
help='ID of image(s) to delete.')
def do_image_delete(gc, args):
"""Delete specified image."""
try:
gc.images.delete(args.id)
except exc.HTTPNotFound:
msg = "No image with an ID of '%s' exists." % args.id
utils.exit(msg)
failure_flag = False
for args_id in args.id:
try:
gc.images.delete(args_id)
except exc.HTTPForbidden:
msg = "You are not permitted to delete the image '%s'." % args_id
utils.print_err(msg)
failure_flag = True
except exc.HTTPNotFound:
msg = "No image with an ID of '%s' exists." % args_id
utils.print_err(msg)
failure_flag = True
except exc.HTTPException as e:
msg = "'%s': Unable to delete image '%s'" % (e, args_id)
utils.print_err(msg)
failure_flag = True
if failure_flag:
utils.exit()
@utils.arg('image_id', metavar='<IMAGE_ID>',