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:
parent
d90c7d6896
commit
bf02b048bf
|
@ -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.
|
||||
|
||||
|
|
|
@ -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'})
|
||||
|
|
|
@ -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>',
|
||||
|
|
Loading…
Reference in New Issue