Merge "Support image deletion in batches in v2"
This commit is contained in:
@@ -286,6 +286,10 @@ def exit(msg='', exit_code=1):
|
|||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
|
def print_err(msg):
|
||||||
|
print(encodeutils.safe_decode(msg), file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
def save_image(data, path):
|
def save_image(data, path):
|
||||||
"""Save an image to the specified path.
|
"""Save an image to the specified path.
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
import argparse
|
||||||
import json
|
import json
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
@@ -106,13 +107,15 @@ class ShellV2Test(testtools.TestCase):
|
|||||||
utils.print_dict = mock.Mock()
|
utils.print_dict = mock.Mock()
|
||||||
utils.save_image = 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:
|
with mock.patch.object(utils, 'exit') as mocked_utils_exit:
|
||||||
mocked_utils_exit.return_value = '%s' % err_msg
|
mocked_utils_exit.return_value = '%s' % err_msg
|
||||||
|
|
||||||
func(self.gc, func_args)
|
func(self.gc, func_args)
|
||||||
|
if err_msg:
|
||||||
mocked_utils_exit.assert_called_once_with(err_msg)
|
mocked_utils_exit.assert_called_once_with(err_msg)
|
||||||
|
else:
|
||||||
|
mocked_utils_exit.assert_called_once_with()
|
||||||
|
|
||||||
def _run_command(self, cmd):
|
def _run_command(self, cmd):
|
||||||
self.shell.main(cmd.split())
|
self.shell.main(cmd.split())
|
||||||
@@ -591,24 +594,49 @@ class ShellV2Test(testtools.TestCase):
|
|||||||
mocked_data.assert_called_once_with('IMG-01')
|
mocked_data.assert_called_once_with('IMG-01')
|
||||||
|
|
||||||
def test_do_image_delete(self):
|
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:
|
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
|
||||||
mocked_delete.return_value = 0
|
mocked_delete.return_value = 0
|
||||||
|
|
||||||
test_shell.do_image_delete(self.gc, args)
|
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):
|
def test_do_image_delete_deleted(self):
|
||||||
image_id = 'deleted-img'
|
image_id = 'deleted-img'
|
||||||
args = self._make_args({'id': image_id})
|
args = argparse.Namespace(id=[image_id])
|
||||||
with mock.patch.object(self.gc.images, 'delete') as mocked_get:
|
with mock.patch.object(self.gc.images, 'delete') as mocked_delete:
|
||||||
mocked_get.side_effect = exc.HTTPNotFound
|
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,
|
self.assert_exits_with_msg(func=test_shell.do_image_delete,
|
||||||
func_args=args,
|
func_args=args)
|
||||||
err_msg=msg)
|
|
||||||
|
|
||||||
def test_do_member_list(self):
|
def test_do_member_list(self):
|
||||||
args = self._make_args({'image_id': 'IMG-01'})
|
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)
|
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):
|
def do_image_delete(gc, args):
|
||||||
"""Delete specified image."""
|
"""Delete specified image."""
|
||||||
|
failure_flag = False
|
||||||
|
for args_id in args.id:
|
||||||
try:
|
try:
|
||||||
gc.images.delete(args.id)
|
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:
|
except exc.HTTPNotFound:
|
||||||
msg = "No image with an ID of '%s' exists." % args.id
|
msg = "No image with an ID of '%s' exists." % args_id
|
||||||
utils.exit(msg)
|
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>',
|
@utils.arg('image_id', metavar='<IMAGE_ID>',
|
||||||
|
Reference in New Issue
Block a user