summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-07-25 00:55:36 +0000
committerGerrit Code Review <review@openstack.org>2018-07-25 00:55:36 +0000
commitccbd86ba131d319e512bf4855e9b3152cc073fee (patch)
treeaf85e0cb27b1c25e32bb722d92bd3f0480bf1f92
parentca34119a34a1daa5f20b368a42efe6ae2454deea (diff)
parentce5a929b9b75ff614d7af025053a990b32fe599b (diff)
downloadpython-glanceclient-ccbd86ba131d319e512bf4855e9b3152cc073fee.tar.gz
Merge "Unit tests for multi-store support"
-rw-r--r--glanceclient/tests/unit/v2/test_shell_v2.py232
1 files changed, 232 insertions, 0 deletions
diff --git a/glanceclient/tests/unit/v2/test_shell_v2.py b/glanceclient/tests/unit/v2/test_shell_v2.py
index b51249d..83fa526 100644
--- a/glanceclient/tests/unit/v2/test_shell_v2.py
+++ b/glanceclient/tests/unit/v2/test_shell_v2.py
@@ -124,6 +124,56 @@ class ShellV2Test(testtools.TestCase):
def _run_command(self, cmd):
self.shell.main(cmd.split())
+ stores_info_response = {
+ "stores": [
+ {
+ "default": "true",
+ "id": "ceph1",
+ "description": "RBD backend for glance."
+ },
+ {
+ "id": "file2",
+ "description": "Filesystem backend for glance."
+ },
+ {
+ "id": "file1",
+ "description": "Filesystem backend for gkance."
+ },
+ {
+ "id": "ceph2",
+ "description": "RBD backend for glance."
+ }
+ ]
+ }
+
+ def test_do_stores_info(self):
+ args = []
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mocked_list:
+ mocked_list.return_value = self.stores_info_response
+
+ test_shell.do_stores_info(self.gc, args)
+
+ mocked_list.assert_called_once_with()
+ utils.print_dict.assert_called_once_with(self.stores_info_response)
+
+ @mock.patch('glanceclient.common.utils.exit')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_neg_stores_info(
+ self, mock_stdin, mock_utils_exit):
+ expected_msg = ('Multi Backend support is not enabled')
+ args = []
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mocked_info:
+ mocked_info.side_effect = exc.HTTPNotFound
+ try:
+ test_shell.do_stores_info(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
@mock.patch('sys.stderr')
def test_image_create_missing_disk_format(self, __):
e = self.assertRaises(exc.CommandError, self._run_command,
@@ -566,6 +616,56 @@ class ShellV2Test(testtools.TestCase):
utils.print_dict.assert_called_once_with({
'id': 'pass', 'name': 'IMG-01', 'myprop': 'myval'})
+ @mock.patch('glanceclient.common.utils.exit')
+ @mock.patch('os.access')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_neg_do_image_create_no_file_and_stdin_with_backend(
+ self, mock_stdin, mock_access, mock_utils_exit):
+ expected_msg = ('--backend option should only be provided with --file '
+ 'option or stdin.')
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ mock_stdin.isatty = lambda: True
+ mock_access.return_value = False
+ args = self._make_args({'name': 'IMG-01',
+ 'property': ['myprop=myval'],
+ 'file': None,
+ 'backend': 'file1',
+ 'container_format': 'bare',
+ 'disk_format': 'qcow2'})
+
+ try:
+ test_shell.do_image_create(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
+ @mock.patch('glanceclient.common.utils.exit')
+ def test_neg_do_image_create_invalid_backend(
+ self, mock_utils_exit):
+ expected_msg = ("Backend 'dummy' is not valid for this cloud. "
+ "Valid values can be retrieved with stores-info "
+ "command.")
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ args = self._make_args({'name': 'IMG-01',
+ 'property': ['myprop=myval'],
+ 'file': "somefile.txt",
+ 'backend': 'dummy',
+ 'container_format': 'bare',
+ 'disk_format': 'qcow2'})
+
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mock_stores_info:
+ mock_stores_info.return_value = self.stores_info_response
+ try:
+ test_shell.do_image_create(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
# NOTE(rosmaita): have to explicitly set to None the declared but unused
# arguments (the configparser does that for us normally)
base_args = {'name': 'Mortimer',
@@ -608,6 +708,87 @@ class ShellV2Test(testtools.TestCase):
mock_utils_exit.assert_called_once_with(expected_msg)
@mock.patch('glanceclient.common.utils.exit')
+ @mock.patch('os.access')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_neg_image_create_via_import_no_file_and_stdin_with_backend(
+ self, mock_stdin, mock_access, mock_utils_exit):
+ expected_msg = ('--backend option should only be provided with --file '
+ 'option or stdin for the glance-direct import method.')
+ my_args = self.base_args.copy()
+ my_args['import_method'] = 'glance-direct'
+ my_args['backend'] = 'file1'
+ args = self._make_args(my_args)
+
+ mock_stdin.isatty = lambda: True
+ mock_access.return_value = False
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ with mock.patch.object(self.gc.images,
+ 'get_import_info') as mocked_info:
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mocked_stores_info:
+ mocked_stores_info.return_value = self.stores_info_response
+ mocked_info.return_value = self.import_info_response
+ try:
+ test_shell.do_image_create_via_import(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
+ @mock.patch('glanceclient.common.utils.exit')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_neg_image_create_via_import_no_uri_with_backend(
+ self, mock_stdin, mock_utils_exit):
+ expected_msg = ('--backend option should only be provided with --uri '
+ 'option for the web-download import method.')
+ my_args = self.base_args.copy()
+ my_args['import_method'] = 'web-download'
+ my_args['backend'] = 'file1'
+ args = self._make_args(my_args)
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ with mock.patch.object(self.gc.images,
+ 'get_import_info') as mocked_info:
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mocked_stores_info:
+ mocked_stores_info.return_value = self.stores_info_response
+ mocked_info.return_value = self.import_info_response
+ try:
+ test_shell.do_image_create_via_import(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
+ @mock.patch('glanceclient.common.utils.exit')
+ @mock.patch('os.access')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_neg_image_create_via_import_invalid_backend(
+ self, mock_stdin, mock_access, mock_utils_exit):
+ expected_msg = ("Backend 'dummy' is not valid for this cloud. "
+ "Valid values can be retrieved with stores-info"
+ " command.")
+ my_args = self.base_args.copy()
+ my_args['import_method'] = 'glance-direct'
+ my_args['backend'] = 'dummy'
+ args = self._make_args(my_args)
+
+ mock_stdin.isatty = lambda: True
+ mock_access.return_value = False
+ mock_utils_exit.side_effect = self._mock_utils_exit
+ with mock.patch.object(self.gc.images,
+ 'get_import_info') as mocked_info:
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mocked_stores_info:
+ mocked_stores_info.return_value = self.stores_info_response
+ mocked_info.return_value = self.import_info_response
+ try:
+ test_shell.do_image_create_via_import(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
+ @mock.patch('glanceclient.common.utils.exit')
@mock.patch('sys.stdin', autospec=True)
def test_neg_image_create_via_import_no_method_passing_uri(
self, mock_stdin, mock_utils_exit):
@@ -1183,6 +1364,28 @@ class ShellV2Test(testtools.TestCase):
backend=None)
@mock.patch('glanceclient.common.utils.exit')
+ def test_image_upload_invalid_backend(self, mock_utils_exit):
+ expected_msg = ("Backend 'dummy' is not valid for this cloud. "
+ "Valid values can be retrieved with stores-info "
+ "command.")
+ mock_utils_exit.side_effect = self._mock_utils_exit
+
+ args = self._make_args(
+ {'id': 'IMG-01', 'file': 'test', 'size': 1024, 'progress': False,
+ 'backend': 'dummy'})
+
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mock_stores_info:
+ mock_stores_info.return_value = self.stores_info_response
+ try:
+ test_shell.do_image_upload(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
+ @mock.patch('glanceclient.common.utils.exit')
def test_neg_image_import_not_available(self, mock_utils_exit):
expected_msg = 'Target Glance does not support Image Import workflow'
mock_utils_exit.side_effect = self._mock_utils_exit
@@ -1327,6 +1530,35 @@ class ShellV2Test(testtools.TestCase):
pass
mock_utils_exit.assert_called_once_with(expected_msg)
+ @mock.patch('glanceclient.common.utils.exit')
+ def test_image_import_invalid_backend(self, mock_utils_exit):
+ expected_msg = ("Backend 'dummy' is not valid for this cloud. "
+ "Valid values can be retrieved with stores-info "
+ "command.")
+ mock_utils_exit.side_effect = self._mock_utils_exit
+
+ args = self._make_args(
+ {'id': 'IMG-01', 'import_method': 'glance-direct', 'uri': None,
+ 'backend': 'dummy'})
+
+ with mock.patch.object(self.gc.images, 'get') as mocked_get:
+ with mock.patch.object(self.gc.images,
+ 'get_import_info') as mocked_info:
+ mocked_get.return_value = {'status': 'uploading',
+ 'container_format': 'bare',
+ 'disk_format': 'raw'}
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as mock_stores_info:
+ mocked_info.return_value = self.import_info_response
+ mock_stores_info.return_value = self.stores_info_response
+ try:
+ test_shell.do_image_import(self.gc, args)
+ self.fail("utils.exit should have been called")
+ except SystemExit:
+ pass
+
+ mock_utils_exit.assert_called_once_with(expected_msg)
+
def test_image_import_glance_direct(self):
args = self._make_args(
{'id': 'IMG-01', 'import_method': 'glance-direct', 'uri': None})