diff options
Diffstat (limited to 'openstackclient/tests')
| -rw-r--r-- | openstackclient/tests/common/test_clientmanager.py | 3 | ||||
| -rw-r--r-- | openstackclient/tests/common/test_utils.py | 39 | ||||
| -rw-r--r-- | openstackclient/tests/compute/v2/test_server.py | 47 | ||||
| -rw-r--r-- | openstackclient/tests/image/v1/test_image.py | 9 | ||||
| -rw-r--r-- | openstackclient/tests/image/v2/test_image.py | 50 | ||||
| -rw-r--r-- | openstackclient/tests/test_shell.py | 447 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/__init__.py | 0 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/fakes.py | 136 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/test_backup.py | 82 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/test_snapshot.py | 82 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/test_type.py | 82 | ||||
| -rw-r--r-- | openstackclient/tests/volume/v2/test_volume.py | 82 |
12 files changed, 842 insertions, 217 deletions
diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index 26cf4967..4e2f46b4 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -12,12 +12,13 @@ # License for the specific language governing permissions and limitations # under the License. # + +import json as jsonutils import mock from requests_mock.contrib import fixture from keystoneclient.auth.identity import v2 as auth_v2 from keystoneclient import service_catalog -from oslo_serialization import jsonutils from openstackclient.api import auth from openstackclient.api import auth_plugin diff --git a/openstackclient/tests/common/test_utils.py b/openstackclient/tests/common/test_utils.py index cda0b135..d9f5b7a5 100644 --- a/openstackclient/tests/common/test_utils.py +++ b/openstackclient/tests/common/test_utils.py @@ -13,6 +13,9 @@ # under the License. # +import time +import uuid + import mock from openstackclient.common import exceptions @@ -120,6 +123,42 @@ class TestUtils(test_utils.TestCase): utils.sort_items, items, sort_str) + @mock.patch.object(time, 'sleep') + def test_wait_for_delete_ok(self, mock_sleep): + # Tests the normal flow that the resource is deleted with a 404 coming + # back on the 2nd iteration of the wait loop. + resource = mock.MagicMock(status='ACTIVE', progress=None) + mock_get = mock.Mock(side_effect=[resource, + exceptions.NotFound(404)]) + manager = mock.MagicMock(get=mock_get) + res_id = str(uuid.uuid4()) + callback = mock.Mock() + self.assertTrue(utils.wait_for_delete(manager, res_id, + callback=callback)) + mock_sleep.assert_called_once_with(5) + callback.assert_called_once_with(0) + + @mock.patch.object(time, 'sleep') + def test_wait_for_delete_timeout(self, mock_sleep): + # Tests that we fail if the resource is not deleted before the timeout. + resource = mock.MagicMock(status='ACTIVE') + mock_get = mock.Mock(return_value=resource) + manager = mock.MagicMock(get=mock_get) + res_id = str(uuid.uuid4()) + self.assertFalse(utils.wait_for_delete(manager, res_id, sleep_time=1, + timeout=1)) + mock_sleep.assert_called_once_with(1) + + @mock.patch.object(time, 'sleep') + def test_wait_for_delete_error(self, mock_sleep): + # Tests that we fail if the resource goes to error state while waiting. + resource = mock.MagicMock(status='ERROR') + mock_get = mock.Mock(return_value=resource) + manager = mock.MagicMock(get=mock_get) + res_id = str(uuid.uuid4()) + self.assertFalse(utils.wait_for_delete(manager, res_id)) + self.assertFalse(mock_sleep.called) + class NoUniqueMatch(Exception): pass diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py index baf53742..a8a1936d 100644 --- a/openstackclient/tests/compute/v2/test_server.py +++ b/openstackclient/tests/compute/v2/test_server.py @@ -16,6 +16,7 @@ import copy import mock +from openstackclient.common import utils as common_utils from openstackclient.compute.v2 import server from openstackclient.tests.compute.v2 import fakes as compute_fakes from openstackclient.tests import fakes @@ -319,6 +320,52 @@ class TestServerDelete(TestServer): compute_fakes.server_id, ) + @mock.patch.object(common_utils, 'wait_for_delete', return_value=True) + def test_server_delete_wait_ok(self, mock_wait_for_delete): + arglist = [ + compute_fakes.server_id, '--wait' + ] + verifylist = [ + ('servers', [compute_fakes.server_id]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + self.servers_mock.delete.assert_called_with( + compute_fakes.server_id, + ) + + mock_wait_for_delete.assert_called_once_with( + self.servers_mock, + compute_fakes.server_id, + callback=server._show_progress + ) + + @mock.patch.object(common_utils, 'wait_for_delete', return_value=False) + def test_server_delete_wait_fails(self, mock_wait_for_delete): + arglist = [ + compute_fakes.server_id, '--wait' + ] + verifylist = [ + ('servers', [compute_fakes.server_id]), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.assertRaises(SystemExit, self.cmd.take_action, parsed_args) + + self.servers_mock.delete.assert_called_with( + compute_fakes.server_id, + ) + + mock_wait_for_delete.assert_called_once_with( + self.servers_mock, + compute_fakes.server_id, + callback=server._show_progress + ) + class TestServerImageCreate(TestServer): diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py index ef7ca9ea..eec8cfa5 100644 --- a/openstackclient/tests/image/v1/test_image.py +++ b/openstackclient/tests/image/v1/test_image.py @@ -547,6 +547,9 @@ class TestImageSet(TestImage): '--owner', 'new-owner', '--min-disk', '2', '--min-ram', '4', + '--container-format', 'ovf', + '--disk-format', 'vmdk', + '--size', '35165824', image_fakes.image_name, ] verifylist = [ @@ -554,6 +557,9 @@ class TestImageSet(TestImage): ('owner', 'new-owner'), ('min_disk', 2), ('min_ram', 4), + ('container_format', 'ovf'), + ('disk_format', 'vmdk'), + ('size', 35165824), ('image', image_fakes.image_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -566,6 +572,9 @@ class TestImageSet(TestImage): 'owner': 'new-owner', 'min_disk': 2, 'min_ram': 4, + 'container_format': 'ovf', + 'disk_format': 'vmdk', + 'size': 35165824 } # ImageManager.update(image, **kwargs) self.images_mock.update.assert_called_with( diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py index 73b5d39a..7cfaf083 100644 --- a/openstackclient/tests/image/v2/test_image.py +++ b/openstackclient/tests/image/v2/test_image.py @@ -331,3 +331,53 @@ class TestImageShow(TestImage): self.assertEqual(image_fakes.IMAGE_columns, columns) self.assertEqual(image_fakes.IMAGE_data, data) + + +class TestImageSet(TestImage): + + def setUp(self): + super(TestImageSet, self).setUp() + # Set up the schema + self.model = warlock.model_factory( + image_fakes.IMAGE_schema, + schemas.SchemaBasedModel, + ) + + self.images_mock.get.return_value = self.model(**image_fakes.IMAGE) + self.images_mock.update.return_value = self.model(**image_fakes.IMAGE) + # Get the command object to test + self.cmd = image.SetImage(self.app, None) + + def test_image_set_options(self): + arglist = [ + '--name', 'new-name', + '--owner', 'new-owner', + '--min-disk', '2', + '--min-ram', '4', + image_fakes.image_id, + ] + verifylist = [ + ('name', 'new-name'), + ('owner', 'new-owner'), + ('min_disk', 2), + ('min_ram', 4), + ('image', image_fakes.image_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + kwargs = { + 'name': 'new-name', + 'owner': 'new-owner', + 'min_disk': 2, + 'min_ram': 4, + 'protected': False + } + # ImageManager.update(image, **kwargs) + self.images_mock.update.assert_called_with( + image_fakes.image_id, **kwargs) + + self.assertEqual(image_fakes.IMAGE_columns, columns) + self.assertEqual(image_fakes.IMAGE_data, data) diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py index 492b60de..8850d8f9 100644 --- a/openstackclient/tests/test_shell.py +++ b/openstackclient/tests/test_shell.py @@ -25,13 +25,15 @@ DEFAULT_AUTH_URL = "http://127.0.0.1:5000/v2.0/" DEFAULT_PROJECT_ID = "xxxx-yyyy-zzzz" DEFAULT_PROJECT_NAME = "project" DEFAULT_DOMAIN_ID = "aaaa-bbbb-cccc" -DEFAULT_DOMAIN_NAME = "domain" +DEFAULT_DOMAIN_NAME = "default" DEFAULT_USER_DOMAIN_ID = "aaaa-bbbb-cccc" DEFAULT_USER_DOMAIN_NAME = "domain" DEFAULT_PROJECT_DOMAIN_ID = "aaaa-bbbb-cccc" DEFAULT_PROJECT_DOMAIN_NAME = "domain" DEFAULT_USERNAME = "username" DEFAULT_PASSWORD = "password" + +DEFAULT_CLOUD = "altocumulus" DEFAULT_REGION_NAME = "ZZ9_Plural_Z_Alpha" DEFAULT_TOKEN = "token" DEFAULT_SERVICE_URL = "http://127.0.0.1:8771/v3.0/" @@ -90,6 +92,54 @@ PUBLIC_1 = { } +# The option table values is a tuple of (<value>, <test-opt>, <test-env>) +# where <value> is the test value to use, <test-opt> is True if this option +# should be tested as a CLI option and <test-env> is True of this option +# should be tested as an environment variable. + +# Global options that should be parsed before shell.initialize_app() is called +global_options = { + '--os-cloud': (DEFAULT_CLOUD, True, True), + '--os-region-name': (DEFAULT_REGION_NAME, True, True), + '--os-default-domain': (DEFAULT_DOMAIN_NAME, True, True), + '--os-cacert': ('/dev/null', True, True), + '--timing': (True, True, False), +} + +auth_options = { + '--os-auth-url': (DEFAULT_AUTH_URL, True, True), + '--os-project-id': (DEFAULT_PROJECT_ID, True, True), + '--os-project-name': (DEFAULT_PROJECT_NAME, True, True), + '--os-domain-id': (DEFAULT_DOMAIN_ID, True, True), + '--os-domain-name': (DEFAULT_DOMAIN_NAME, True, True), + '--os-user-domain-id': (DEFAULT_USER_DOMAIN_ID, True, True), + '--os-user-domain-name': (DEFAULT_USER_DOMAIN_NAME, True, True), + '--os-project-domain-id': (DEFAULT_PROJECT_DOMAIN_ID, True, True), + '--os-project-domain-name': (DEFAULT_PROJECT_DOMAIN_NAME, True, True), + '--os-username': (DEFAULT_USERNAME, True, True), + '--os-password': (DEFAULT_PASSWORD, True, True), + '--os-region-name': (DEFAULT_REGION_NAME, True, True), + '--os-trust-id': ("1234", True, True), + '--os-auth-type': ("v2password", True, True), + '--os-token': (DEFAULT_TOKEN, True, True), + '--os-url': (DEFAULT_SERVICE_URL, True, True), +} + + +def opt2attr(opt): + if opt.startswith('--os-'): + attr = opt[5:] + elif opt.startswith('--'): + attr = opt[2:] + else: + attr = opt + return attr.lower().replace('-', '_') + + +def opt2env(opt): + return opt[2:].upper().replace('-', '_') + + def make_shell(): """Create a new command shell and mock out some bits.""" _shell = shell.OpenStackShell() @@ -115,69 +165,54 @@ class TestShell(utils.TestCase): super(TestShell, self).tearDown() self.cmd_patch.stop() - def _assert_password_auth(self, cmd_options, default_args): - with mock.patch("openstackclient.shell.OpenStackShell.initialize_app", - self.app): + def _assert_initialize_app_arg(self, cmd_options, default_args): + """Check the args passed to initialize_app() + + The argv argument to initialize_app() is the remainder from parsing + global options declared in both cliff.app and + openstackclient.OpenStackShell build_option_parser(). Any global + options passed on the commmad line should not be in argv but in + _shell.options. + """ + + with mock.patch( + "openstackclient.shell.OpenStackShell.initialize_app", + self.app, + ): _shell, _cmd = make_shell(), cmd_options + " list project" fake_execute(_shell, _cmd) self.app.assert_called_with(["list", "project"]) - self.assertEqual( - default_args.get("auth_url", ''), - _shell.options.auth_url, - ) - self.assertEqual( - default_args.get("project_id", ''), - _shell.options.project_id, - ) - self.assertEqual( - default_args.get("project_name", ''), - _shell.options.project_name, - ) - self.assertEqual( - default_args.get("domain_id", ''), - _shell.options.domain_id, - ) - self.assertEqual( - default_args.get("domain_name", ''), - _shell.options.domain_name, - ) - self.assertEqual( - default_args.get("user_domain_id", ''), - _shell.options.user_domain_id, - ) - self.assertEqual( - default_args.get("user_domain_name", ''), - _shell.options.user_domain_name, - ) - self.assertEqual( - default_args.get("project_domain_id", ''), - _shell.options.project_domain_id, - ) - self.assertEqual( - default_args.get("project_domain_name", ''), - _shell.options.project_domain_name, - ) - self.assertEqual( - default_args.get("username", ''), - _shell.options.username, - ) - self.assertEqual( - default_args.get("password", ''), - _shell.options.password, - ) - self.assertEqual( - default_args.get("region_name", ''), - _shell.options.region_name, - ) - self.assertEqual( - default_args.get("trust_id", ''), - _shell.options.trust_id, - ) - self.assertEqual( - default_args.get('auth_type', ''), - _shell.options.auth_type, - ) + for k in default_args.keys(): + self.assertEqual( + default_args[k], + vars(_shell.options)[k], + "%s does not match" % k, + ) + + def _assert_cloud_config_arg(self, cmd_options, default_args): + """Check the args passed to cloud_config.get_one_cloud() + + The argparse argument to get_one_cloud() is an argparse.Namespace + object that contains all of the options processed to this point in + initialize_app(). + """ + + self.occ_get_one = mock.Mock("Test Shell") + with mock.patch( + "os_client_config.config.OpenStackConfig.get_one_cloud", + self.occ_get_one, + ): + _shell, _cmd = make_shell(), cmd_options + " list project" + fake_execute(_shell, _cmd) + + opts = self.occ_get_one.call_args[1]['argparse'] + for k in default_args.keys(): + self.assertEqual( + default_args[k], + vars(opts)[k], + "%s does not match" % k, + ) def _assert_token_auth(self, cmd_options, default_args): with mock.patch("openstackclient.shell.OpenStackShell.initialize_app", @@ -258,136 +293,91 @@ class TestShellHelp(TestShell): _shell.options.deferred_help) -class TestShellPasswordAuth(TestShell): +class TestShellOptions(TestShell): def setUp(self): - super(TestShellPasswordAuth, self).setUp() + super(TestShellOptions, self).setUp() self.orig_env, os.environ = os.environ, {} def tearDown(self): - super(TestShellPasswordAuth, self).tearDown() + super(TestShellOptions, self).tearDown() os.environ = self.orig_env - def test_only_url_flow(self): - flag = "--os-auth-url " + DEFAULT_AUTH_URL - kwargs = { - "auth_url": DEFAULT_AUTH_URL, - } - self._assert_password_auth(flag, kwargs) - - def test_only_project_id_flow(self): - flag = "--os-project-id " + DEFAULT_PROJECT_ID - kwargs = { - "project_id": DEFAULT_PROJECT_ID, - } - self._assert_password_auth(flag, kwargs) - - def test_only_project_name_flow(self): - flag = "--os-project-name " + DEFAULT_PROJECT_NAME - kwargs = { - "project_name": DEFAULT_PROJECT_NAME, - } - self._assert_password_auth(flag, kwargs) - - def test_only_domain_id_flow(self): - flag = "--os-domain-id " + DEFAULT_DOMAIN_ID - kwargs = { - "domain_id": DEFAULT_DOMAIN_ID, - } - self._assert_password_auth(flag, kwargs) - - def test_only_domain_name_flow(self): - flag = "--os-domain-name " + DEFAULT_DOMAIN_NAME - kwargs = { - "domain_name": DEFAULT_DOMAIN_NAME, - } - self._assert_password_auth(flag, kwargs) - - def test_only_user_domain_id_flow(self): - flag = "--os-user-domain-id " + DEFAULT_USER_DOMAIN_ID - kwargs = { - "user_domain_id": DEFAULT_USER_DOMAIN_ID, - } - self._assert_password_auth(flag, kwargs) + def _test_options_init_app(self, test_opts): + for opt in test_opts.keys(): + if not test_opts[opt][1]: + continue + key = opt2attr(opt) + if type(test_opts[opt][0]) is str: + cmd = opt + " " + test_opts[opt][0] + else: + cmd = opt + kwargs = { + key: test_opts[opt][0], + } + self._assert_initialize_app_arg(cmd, kwargs) + + def _test_options_get_one_cloud(self, test_opts): + for opt in test_opts.keys(): + if not test_opts[opt][1]: + continue + key = opt2attr(opt) + if type(test_opts[opt][0]) is str: + cmd = opt + " " + test_opts[opt][0] + else: + cmd = opt + kwargs = { + key: test_opts[opt][0], + } + self._assert_cloud_config_arg(cmd, kwargs) + + def _test_env_init_app(self, test_opts): + for opt in test_opts.keys(): + if not test_opts[opt][2]: + continue + key = opt2attr(opt) + kwargs = { + key: test_opts[opt][0], + } + env = { + opt2env(opt): test_opts[opt][0], + } + os.environ = env.copy() + self._assert_initialize_app_arg("", kwargs) + + def _test_env_get_one_cloud(self, test_opts): + for opt in test_opts.keys(): + if not test_opts[opt][2]: + continue + key = opt2attr(opt) + kwargs = { + key: test_opts[opt][0], + } + env = { + opt2env(opt): test_opts[opt][0], + } + os.environ = env.copy() + self._assert_cloud_config_arg("", kwargs) - def test_only_user_domain_name_flow(self): - flag = "--os-user-domain-name " + DEFAULT_USER_DOMAIN_NAME - kwargs = { - "user_domain_name": DEFAULT_USER_DOMAIN_NAME, - } - self._assert_password_auth(flag, kwargs) + def test_empty_auth(self): + os.environ = {} + self._assert_initialize_app_arg("", {}) + self._assert_cloud_config_arg("", {}) - def test_only_project_domain_id_flow(self): - flag = "--os-project-domain-id " + DEFAULT_PROJECT_DOMAIN_ID - kwargs = { - "project_domain_id": DEFAULT_PROJECT_DOMAIN_ID, - } - self._assert_password_auth(flag, kwargs) + def test_global_options(self): + self._test_options_init_app(global_options) + self._test_options_get_one_cloud(global_options) - def test_only_project_domain_name_flow(self): - flag = "--os-project-domain-name " + DEFAULT_PROJECT_DOMAIN_NAME - kwargs = { - "project_domain_name": DEFAULT_PROJECT_DOMAIN_NAME, - } - self._assert_password_auth(flag, kwargs) + def test_auth_options(self): + self._test_options_init_app(auth_options) + self._test_options_get_one_cloud(auth_options) - def test_only_username_flow(self): - flag = "--os-username " + DEFAULT_USERNAME - kwargs = { - "username": DEFAULT_USERNAME, - } - self._assert_password_auth(flag, kwargs) - - def test_only_password_flow(self): - flag = "--os-password " + DEFAULT_PASSWORD - kwargs = { - "password": DEFAULT_PASSWORD, - } - self._assert_password_auth(flag, kwargs) + def test_global_env(self): + self._test_env_init_app(global_options) + self._test_env_get_one_cloud(global_options) - def test_only_region_name_flow(self): - flag = "--os-region-name " + DEFAULT_REGION_NAME - kwargs = { - "region_name": DEFAULT_REGION_NAME, - } - self._assert_password_auth(flag, kwargs) - - def test_only_trust_id_flow(self): - flag = "--os-trust-id " + "1234" - kwargs = { - "trust_id": "1234", - } - self._assert_password_auth(flag, kwargs) - - def test_only_auth_type_flow(self): - flag = "--os-auth-type " + "v2password" - kwargs = { - "auth_type": DEFAULT_AUTH_PLUGIN - } - self._assert_password_auth(flag, kwargs) - - -class TestShellTokenAuth(TestShell): - def test_only_token(self): - flag = "--os-token " + DEFAULT_TOKEN - kwargs = { - "token": DEFAULT_TOKEN, - "auth_url": '', - } - self._assert_token_auth(flag, kwargs) - - def test_only_auth_url(self): - flag = "--os-auth-url " + DEFAULT_AUTH_URL - kwargs = { - "token": '', - "auth_url": DEFAULT_AUTH_URL, - } - self._assert_token_auth(flag, kwargs) - - def test_empty_auth(self): - os.environ = {} - flag = "" - kwargs = {} - self._assert_token_auth(flag, kwargs) + def test_auth_env(self): + self._test_env_init_app(auth_options) + self._test_env_get_one_cloud(auth_options) class TestShellTokenAuthEnv(TestShell): @@ -437,33 +427,6 @@ class TestShellTokenAuthEnv(TestShell): self._assert_token_auth(flag, kwargs) -class TestShellTokenEndpointAuth(TestShell): - def test_only_token(self): - flag = "--os-token " + DEFAULT_TOKEN - kwargs = { - "token": DEFAULT_TOKEN, - "url": '', - } - self._assert_token_endpoint_auth(flag, kwargs) - - def test_only_url(self): - flag = "--os-url " + DEFAULT_SERVICE_URL - kwargs = { - "token": '', - "url": DEFAULT_SERVICE_URL, - } - self._assert_token_endpoint_auth(flag, kwargs) - - def test_empty_auth(self): - os.environ = {} - flag = "" - kwargs = { - "token": '', - "auth_url": '', - } - self._assert_token_endpoint_auth(flag, kwargs) - - class TestShellTokenEndpointAuthEnv(TestShell): def setUp(self): super(TestShellTokenEndpointAuthEnv, self).setUp() @@ -527,13 +490,65 @@ class TestShellCli(TestShell): super(TestShellCli, self).tearDown() os.environ = self.orig_env - def test_shell_args(self): + def test_shell_args_no_options(self): _shell = make_shell() with mock.patch("openstackclient.shell.OpenStackShell.initialize_app", self.app): fake_execute(_shell, "list user") self.app.assert_called_with(["list", "user"]) + def test_shell_args_ca_options(self): + _shell = make_shell() + + # NOTE(dtroyer): The commented out asserts below are the desired + # behaviour and will be uncommented when the + # handling for --verify and --insecure is fixed. + + # Default + fake_execute(_shell, "list user") + self.assertIsNone(_shell.options.verify) + self.assertIsNone(_shell.options.insecure) + self.assertEqual('', _shell.options.cacert) + self.assertTrue(_shell.verify) + + # --verify + fake_execute(_shell, "--verify list user") + self.assertTrue(_shell.options.verify) + self.assertIsNone(_shell.options.insecure) + self.assertEqual('', _shell.options.cacert) + self.assertTrue(_shell.verify) + + # --insecure + fake_execute(_shell, "--insecure list user") + self.assertIsNone(_shell.options.verify) + self.assertTrue(_shell.options.insecure) + self.assertEqual('', _shell.options.cacert) + self.assertFalse(_shell.verify) + + # --os-cacert + fake_execute(_shell, "--os-cacert foo list user") + self.assertIsNone(_shell.options.verify) + self.assertIsNone(_shell.options.insecure) + self.assertEqual('foo', _shell.options.cacert) + self.assertTrue(_shell.verify) + + # --os-cacert and --verify + fake_execute(_shell, "--os-cacert foo --verify list user") + self.assertTrue(_shell.options.verify) + self.assertIsNone(_shell.options.insecure) + self.assertEqual('foo', _shell.options.cacert) + self.assertTrue(_shell.verify) + + # --os-cacert and --insecure + # NOTE(dtroyer): This really is a bogus combination, the default is + # to follow the requests.Session convention and let + # --os-cacert override --insecure + fake_execute(_shell, "--os-cacert foo --insecure list user") + self.assertIsNone(_shell.options.verify) + self.assertTrue(_shell.options.insecure) + self.assertEqual('foo', _shell.options.cacert) + self.assertTrue(_shell.verify) + def test_default_env(self): flag = "" kwargs = { @@ -559,7 +574,7 @@ class TestShellCli(TestShell): @mock.patch("os_client_config.config.OpenStackConfig._load_config_file") def test_shell_args_cloud_no_vendor(self, config_mock): - config_mock.return_value = copy.deepcopy(CLOUD_1) + config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_1)) _shell = make_shell() fake_execute( @@ -596,8 +611,8 @@ class TestShellCli(TestShell): @mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file") @mock.patch("os_client_config.config.OpenStackConfig._load_config_file") def test_shell_args_cloud_public(self, config_mock, public_mock): - config_mock.return_value = copy.deepcopy(CLOUD_2) - public_mock.return_value = copy.deepcopy(PUBLIC_1) + config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2)) + public_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1)) _shell = make_shell() fake_execute( @@ -636,8 +651,8 @@ class TestShellCli(TestShell): @mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file") @mock.patch("os_client_config.config.OpenStackConfig._load_config_file") def test_shell_args_precedence(self, config_mock, vendor_mock): - config_mock.return_value = copy.deepcopy(CLOUD_2) - vendor_mock.return_value = copy.deepcopy(PUBLIC_1) + config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2)) + vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1)) _shell = make_shell() # Test command option overriding config file value @@ -690,8 +705,8 @@ class TestShellCliEnv(TestShell): @mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file") @mock.patch("os_client_config.config.OpenStackConfig._load_config_file") def test_shell_args_precedence_1(self, config_mock, vendor_mock): - config_mock.return_value = copy.deepcopy(CLOUD_2) - vendor_mock.return_value = copy.deepcopy(PUBLIC_1) + config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2)) + vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1)) _shell = make_shell() # Test env var @@ -731,8 +746,8 @@ class TestShellCliEnv(TestShell): @mock.patch("os_client_config.config.OpenStackConfig._load_vendor_file") @mock.patch("os_client_config.config.OpenStackConfig._load_config_file") def test_shell_args_precedence_2(self, config_mock, vendor_mock): - config_mock.return_value = copy.deepcopy(CLOUD_2) - vendor_mock.return_value = copy.deepcopy(PUBLIC_1) + config_mock.return_value = ('file.yaml', copy.deepcopy(CLOUD_2)) + vendor_mock.return_value = ('file.yaml', copy.deepcopy(PUBLIC_1)) _shell = make_shell() # Test command option overriding config file value diff --git a/openstackclient/tests/volume/v2/__init__.py b/openstackclient/tests/volume/v2/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/openstackclient/tests/volume/v2/__init__.py diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py new file mode 100644 index 00000000..3eade391 --- /dev/null +++ b/openstackclient/tests/volume/v2/fakes.py @@ -0,0 +1,136 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 mock + +from openstackclient.tests import fakes +from openstackclient.tests.identity.v2_0 import fakes as identity_fakes +from openstackclient.tests import utils + +volume_id = "ce26708d-a7f8-4b4b-9861-4a80256615a6" +volume_name = "fake_volume" +volume_description = "fake description" +volume_status = "available" +volume_size = 20 +volume_type = "fake_lvmdriver-1" +volume_metadata = { + "foo": "bar" +} +volume_snapshot_id = 1 +volume_availability_zone = "nova" +volume_attachments = ["fake_attachments"] + +VOLUME = { + "id": volume_id, + "name": volume_name, + "description": volume_description, + "status": volume_status, + "size": volume_size, + "volume_type": volume_type, + "metadata": volume_metadata, + "snapshot_id": volume_snapshot_id, + "availability_zone": volume_availability_zone, + "attachments": volume_attachments +} + +VOLUME_columns = tuple(sorted(VOLUME)) +VOLUME_data = tuple((VOLUME[x] for x in sorted(VOLUME))) + + +snapshot_id = "cb2d364e-4d1c-451a-8c68-b5bbcb340fb2" +snapshot_name = "fake_snapshot" +snapshot_description = "fake description" +snapshot_size = 10 +snapshot_metadata = { + "foo": "bar" +} +snapshot_volume_id = "bdbae8dc-e6ca-43c0-8076-951cc1b093a4" + +SNAPSHOT = { + "id": snapshot_id, + "name": snapshot_name, + "description": snapshot_description, + "size": snapshot_size, + "metadata": snapshot_metadata +} + +SNAPSHOT_columns = tuple(sorted(SNAPSHOT)) +SNAPSHOT_data = tuple((SNAPSHOT[x] for x in sorted(SNAPSHOT))) + + +type_id = "5520dc9e-6f9b-4378-a719-729911c0f407" +type_description = "fake description" +type_name = "fake-lvmdriver-1" +type_extra_specs = { + "foo": "bar" +} + +TYPE = { + 'id': type_id, + 'name': type_name, + 'description': type_description, + 'extra_specs': type_extra_specs +} + +TYPE_columns = tuple(sorted(TYPE)) +TYPE_data = tuple((TYPE[x] for x in sorted(TYPE))) + +backup_id = "3c409fe6-4d03-4a06-aeab-18bdcdf3c8f4" +backup_volume_id = "bdbae8dc-e6ca-43c0-8076-951cc1b093a4" +backup_name = "fake_backup" +backup_description = "fake description" +backup_object_count = None +backup_container = None +backup_size = 10 + +BACKUP = { + "id": backup_id, + "name": backup_name, + "volume_id": backup_volume_id, + "description": backup_description, + "object_count": backup_object_count, + "container": backup_container, + "size": backup_size +} + +BACKUP_columns = tuple(sorted(BACKUP)) +BACKUP_data = tuple((BACKUP[x] for x in sorted(BACKUP))) + + +class FakeVolumeClient(object): + def __init__(self, **kwargs): + self.volumes = mock.Mock() + self.volumes.resource_class = fakes.FakeResource(None, {}) + self.volume_snapshots = mock.Mock() + self.volume_snapshots.resource_class = fakes.FakeResource(None, {}) + self.backups = mock.Mock() + self.backups.resource_class = fakes.FakeResource(None, {}) + self.volume_types = mock.Mock() + self.volume_types.resource_class = fakes.FakeResource(None, {}) + self.auth_token = kwargs['token'] + self.management_url = kwargs['endpoint'] + + +class TestVolume(utils.TestCommand): + def setUp(self): + super(TestVolume, self).setUp() + + self.app.client_manager.volume = FakeVolumeClient( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN + ) + self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN + ) diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py new file mode 100644 index 00000000..e24cac3c --- /dev/null +++ b/openstackclient/tests/volume/v2/test_backup.py @@ -0,0 +1,82 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 copy + +from openstackclient.tests import fakes +from openstackclient.tests.volume.v2 import fakes as volume_fakes +from openstackclient.volume.v2 import backup + + +class TestBackup(volume_fakes.TestVolume): + + def setUp(self): + super(TestBackup, self).setUp() + + self.backups_mock = self.app.client_manager.volume.backups + self.backups_mock.reset_mock() + + +class TestBackupShow(TestBackup): + def setUp(self): + super(TestBackupShow, self).setUp() + + self.backups_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.BACKUP), + loaded=True) + # Get the command object to test + self.cmd = backup.ShowBackup(self.app, None) + + def test_backup_show(self): + arglist = [ + volume_fakes.backup_id + ] + verifylist = [ + ("backup", volume_fakes.backup_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.backups_mock.get.assert_called_with(volume_fakes.backup_id) + + self.assertEqual(volume_fakes.BACKUP_columns, columns) + self.assertEqual(volume_fakes.BACKUP_data, data) + + +class TestBackupDelete(TestBackup): + def setUp(self): + super(TestBackupDelete, self).setUp() + + self.backups_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.BACKUP), + loaded=True) + self.backups_mock.delete.return_value = None + + # Get the command object to mock + self.cmd = backup.DeleteBackup(self.app, None) + + def test_backup_delete(self): + arglist = [ + volume_fakes.backup_id + ] + verifylist = [ + ("backups", [volume_fakes.backup_id]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + self.backups_mock.delete.assert_called_with(volume_fakes.backup_id) diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py new file mode 100644 index 00000000..91015410 --- /dev/null +++ b/openstackclient/tests/volume/v2/test_snapshot.py @@ -0,0 +1,82 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 copy + +from openstackclient.tests import fakes +from openstackclient.tests.volume.v2 import fakes as volume_fakes +from openstackclient.volume.v2 import snapshot + + +class TestSnapshot(volume_fakes.TestVolume): + + def setUp(self): + super(TestSnapshot, self).setUp() + + self.snapshots_mock = self.app.client_manager.volume.volume_snapshots + self.snapshots_mock.reset_mock() + + +class TestSnapshotShow(TestSnapshot): + def setUp(self): + super(TestSnapshotShow, self).setUp() + + self.snapshots_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.SNAPSHOT), + loaded=True) + # Get the command object to test + self.cmd = snapshot.ShowSnapshot(self.app, None) + + def test_snapshot_show(self): + arglist = [ + volume_fakes.snapshot_id + ] + verifylist = [ + ("snapshot", volume_fakes.snapshot_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.snapshots_mock.get.assert_called_with(volume_fakes.snapshot_id) + + self.assertEqual(volume_fakes.SNAPSHOT_columns, columns) + self.assertEqual(volume_fakes.SNAPSHOT_data, data) + + +class TestSnapshotDelete(TestSnapshot): + def setUp(self): + super(TestSnapshotDelete, self).setUp() + + self.snapshots_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.SNAPSHOT), + loaded=True) + self.snapshots_mock.delete.return_value = None + + # Get the command object to mock + self.cmd = snapshot.DeleteSnapshot(self.app, None) + + def test_snapshot_delete(self): + arglist = [ + volume_fakes.snapshot_id + ] + verifylist = [ + ("snapshots", [volume_fakes.snapshot_id]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + self.snapshots_mock.delete.assert_called_with(volume_fakes.snapshot_id) diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py new file mode 100644 index 00000000..6cc988b2 --- /dev/null +++ b/openstackclient/tests/volume/v2/test_type.py @@ -0,0 +1,82 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 copy + +from openstackclient.tests import fakes +from openstackclient.tests.volume.v2 import fakes as volume_fakes +from openstackclient.volume.v2 import volume_type + + +class TestType(volume_fakes.TestVolume): + + def setUp(self): + super(TestType, self).setUp() + + self.types_mock = self.app.client_manager.volume.volume_types + self.types_mock.reset_mock() + + +class TestTypeShow(TestType): + def setUp(self): + super(TestTypeShow, self).setUp() + + self.types_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.TYPE), + loaded=True) + # Get the command object to test + self.cmd = volume_type.ShowVolumeType(self.app, None) + + def test_type_show(self): + arglist = [ + volume_fakes.type_id + ] + verifylist = [ + ("volume_type", volume_fakes.type_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.types_mock.get.assert_called_with(volume_fakes.type_id) + + self.assertEqual(volume_fakes.TYPE_columns, columns) + self.assertEqual(volume_fakes.TYPE_data, data) + + +class TestTypeDelete(TestType): + def setUp(self): + super(TestTypeDelete, self).setUp() + + self.types_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.TYPE), + loaded=True) + self.types_mock.delete.return_value = None + + # Get the command object to mock + self.cmd = volume_type.DeleteVolumeType(self.app, None) + + def test_type_delete(self): + arglist = [ + volume_fakes.type_id + ] + verifylist = [ + ("volume_type", volume_fakes.type_id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + self.types_mock.delete.assert_called_with(volume_fakes.type_id) diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py new file mode 100644 index 00000000..9e991b72 --- /dev/null +++ b/openstackclient/tests/volume/v2/test_volume.py @@ -0,0 +1,82 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# 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 copy + +from openstackclient.tests import fakes +from openstackclient.tests.volume.v2 import fakes as volume_fakes +from openstackclient.volume.v2 import volume + + +class TestVolume(volume_fakes.TestVolume): + + def setUp(self): + super(TestVolume, self).setUp() + + self.volumes_mock = self.app.client_manager.volume.volumes + self.volumes_mock.reset_mock() + + +class TestVolumeShow(TestVolume): + def setUp(self): + super(TestVolumeShow, self).setUp() + + self.volumes_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.VOLUME), + loaded=True) + # Get the command object to test + self.cmd = volume.ShowVolume(self.app, None) + + def test_volume_show(self): + arglist = [ + volume_fakes.volume_id + ] + verifylist = [ + ("volume", volume_fakes.volume_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.volumes_mock.get.assert_called_with(volume_fakes.volume_id) + + self.assertEqual(volume_fakes.VOLUME_columns, columns) + self.assertEqual(volume_fakes.VOLUME_data, data) + + +class TestVolumeDelete(TestVolume): + def setUp(self): + super(TestVolumeDelete, self).setUp() + + self.volumes_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(volume_fakes.VOLUME), + loaded=True) + self.volumes_mock.delete.return_value = None + + # Get the command object to mock + self.cmd = volume.DeleteVolume(self.app, None) + + def test_volume_delete(self): + arglist = [ + volume_fakes.volume_id + ] + verifylist = [ + ("volumes", [volume_fakes.volume_id]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + self.volumes_mock.delete.assert_called_with(volume_fakes.volume_id) |
