 6f0462732a
			
		
	
	6f0462732a
	
	
	
		
			
			setUp will be automatically called around each testcase, so this is to remove setUp that doing nothing additional than super to keep code clean. Change-Id: I47be2be6f0e9785eb166f89d411582d6292babc1
		
			
				
	
	
		
			440 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			440 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #   Copyright 2012-2013 OpenStack Foundation
 | |
| #
 | |
| #   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
 | |
| import os
 | |
| import sys
 | |
| 
 | |
| from osc_lib.tests import utils as osc_lib_test_utils
 | |
| from oslo_utils import importutils
 | |
| import wrapt
 | |
| 
 | |
| from openstackclient import shell
 | |
| 
 | |
| 
 | |
| 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 = "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/"
 | |
| DEFAULT_AUTH_PLUGIN = "v2password"
 | |
| DEFAULT_INTERFACE = "internal"
 | |
| 
 | |
| DEFAULT_COMPUTE_API_VERSION = ""
 | |
| DEFAULT_IDENTITY_API_VERSION = ""
 | |
| DEFAULT_IMAGE_API_VERSION = ""
 | |
| DEFAULT_VOLUME_API_VERSION = ""
 | |
| DEFAULT_NETWORK_API_VERSION = ""
 | |
| 
 | |
| LIB_COMPUTE_API_VERSION = ""
 | |
| LIB_IDENTITY_API_VERSION = ""
 | |
| LIB_IMAGE_API_VERSION = ""
 | |
| LIB_VOLUME_API_VERSION = ""
 | |
| LIB_NETWORK_API_VERSION = ""
 | |
| 
 | |
| CLOUD_1 = {
 | |
|     'clouds': {
 | |
|         'scc': {
 | |
|             'auth': {
 | |
|                 'auth_url': DEFAULT_AUTH_URL,
 | |
|                 'project_name': DEFAULT_PROJECT_NAME,
 | |
|                 'username': 'zaphod',
 | |
|             },
 | |
|             'region_name': 'occ-cloud',
 | |
|             'donut': 'glazed',
 | |
|             'interface': 'public',
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| CLOUD_2 = {
 | |
|     'clouds': {
 | |
|         'megacloud': {
 | |
|             'cloud': 'megadodo',
 | |
|             'auth': {
 | |
|                 'project_name': 'heart-o-gold',
 | |
|                 'username': 'zaphod',
 | |
|             },
 | |
|             'region_name': 'occ-cloud,krikkit,occ-env',
 | |
|             'log_file': '/tmp/test_log_file',
 | |
|             'log_level': 'debug',
 | |
|             'cert': 'mycert',
 | |
|             'key': 'mickey',
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| PUBLIC_1 = {
 | |
|     'public-clouds': {
 | |
|         'megadodo': {
 | |
|             'auth': {
 | |
|                 'auth_url': DEFAULT_AUTH_URL,
 | |
|                 'project_name': DEFAULT_PROJECT_NAME,
 | |
|             },
 | |
|             'region_name': 'occ-public',
 | |
|             'donut': 'cake',
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| # 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),
 | |
|     '--os-profile': ('SECRET_KEY', True, False),
 | |
|     '--os-interface': (DEFAULT_INTERFACE, True, True)
 | |
| }
 | |
| 
 | |
| 
 | |
| # Wrap the osc_lib make_shell() function to set the shell class since
 | |
| # osc-lib's TestShell class doesn't allow us to specify it yet.
 | |
| # TODO(dtroyer): remove this once the shell_class_patch patch is released
 | |
| #                in osc-lib
 | |
| def make_shell_wrapper(func, inst, args, kwargs):
 | |
|     if 'shell_class' not in kwargs:
 | |
|         kwargs['shell_class'] = shell.OpenStackShell
 | |
|     return func(*args, **kwargs)
 | |
| 
 | |
| 
 | |
| wrapt.wrap_function_wrapper(
 | |
|     osc_lib_test_utils,
 | |
|     'make_shell',
 | |
|     make_shell_wrapper,
 | |
| )
 | |
| 
 | |
| 
 | |
| class TestShell(osc_lib_test_utils.TestShell):
 | |
| 
 | |
|     # Full name of the OpenStackShell class to test (cliff.app.App subclass)
 | |
|     shell_class_name = "openstackclient.shell.OpenStackShell"
 | |
| 
 | |
|     # TODO(dtroyer): remove this once the shell_class_patch patch is released
 | |
|     #                in osc-lib
 | |
|     app_patch = shell_class_name
 | |
| 
 | |
|     def setUp(self):
 | |
|         super(TestShell, self).setUp()
 | |
|         # TODO(dtroyer): remove this once the shell_class_patch patch is
 | |
|         #                released in osc-lib
 | |
|         self.shell_class = importutils.import_class(self.shell_class_name)
 | |
| 
 | |
|     def _assert_token_endpoint_auth(self, cmd_options, default_args):
 | |
|         with mock.patch(
 | |
|                 self.shell_class_name + ".initialize_app",
 | |
|                 self.app,
 | |
|         ):
 | |
|             _shell = osc_lib_test_utils.make_shell(
 | |
|                 shell_class=self.shell_class,
 | |
|             )
 | |
|             _cmd = cmd_options + " list role"
 | |
|             osc_lib_test_utils.fake_execute(_shell, _cmd)
 | |
|             print("_shell: %s" % _shell)
 | |
| 
 | |
|             self.app.assert_called_with(["list", "role"])
 | |
|             self.assertEqual(
 | |
|                 default_args.get("token", ''),
 | |
|                 _shell.options.token,
 | |
|                 "token",
 | |
|             )
 | |
|             self.assertEqual(
 | |
|                 default_args.get("url", ''),
 | |
|                 _shell.options.url,
 | |
|                 "url",
 | |
|             )
 | |
| 
 | |
|     def _assert_token_auth(self, cmd_options, default_args):
 | |
|         with mock.patch(
 | |
|                 self.app_patch + ".initialize_app",
 | |
|                 self.app,
 | |
|         ):
 | |
|             _shell = osc_lib_test_utils.make_shell(
 | |
|                 shell_class=self.shell_class,
 | |
|             )
 | |
|             _cmd = cmd_options + " list role"
 | |
|             osc_lib_test_utils.fake_execute(_shell, _cmd)
 | |
|             print("_shell: %s" % _shell)
 | |
| 
 | |
|             self.app.assert_called_with(["list", "role"])
 | |
|             self.assertEqual(
 | |
|                 default_args.get("token", ''),
 | |
|                 _shell.options.token,
 | |
|                 "token"
 | |
|             )
 | |
|             self.assertEqual(
 | |
|                 default_args.get("auth_url", ''),
 | |
|                 _shell.options.auth_url,
 | |
|                 "auth_url"
 | |
|             )
 | |
| 
 | |
|     def _assert_cli(self, cmd_options, default_args):
 | |
|         with mock.patch(
 | |
|                 self.shell_class_name + ".initialize_app",
 | |
|                 self.app,
 | |
|         ):
 | |
|             _shell = osc_lib_test_utils.make_shell(
 | |
|                 shell_class=self.shell_class,
 | |
|             )
 | |
|             _cmd = cmd_options + " list server"
 | |
|             osc_lib_test_utils.fake_execute(_shell, _cmd)
 | |
| 
 | |
|             self.app.assert_called_with(["list", "server"])
 | |
|             self.assertEqual(default_args["compute_api_version"],
 | |
|                              _shell.options.os_compute_api_version)
 | |
|             self.assertEqual(default_args["identity_api_version"],
 | |
|                              _shell.options.os_identity_api_version)
 | |
|             self.assertEqual(default_args["image_api_version"],
 | |
|                              _shell.options.os_image_api_version)
 | |
|             self.assertEqual(default_args["volume_api_version"],
 | |
|                              _shell.options.os_volume_api_version)
 | |
|             self.assertEqual(default_args["network_api_version"],
 | |
|                              _shell.options.os_network_api_version)
 | |
| 
 | |
| 
 | |
| class TestShellOptions(TestShell):
 | |
| 
 | |
|     def setUp(self):
 | |
|         super(TestShellOptions, self).setUp()
 | |
|         self.useFixture(osc_lib_test_utils.EnvFixture())
 | |
| 
 | |
|     def _test_options_init_app(self, test_opts):
 | |
|         for opt in test_opts.keys():
 | |
|             if not test_opts[opt][1]:
 | |
|                 continue
 | |
|             key = osc_lib_test_utils.opt2attr(opt)
 | |
|             if isinstance(test_opts[opt][0], 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 = osc_lib_test_utils.opt2attr(opt)
 | |
|             if isinstance(test_opts[opt][0], 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 = osc_lib_test_utils.opt2attr(opt)
 | |
|             kwargs = {
 | |
|                 key: test_opts[opt][0],
 | |
|             }
 | |
|             env = {
 | |
|                 osc_lib_test_utils.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 = osc_lib_test_utils.opt2attr(opt)
 | |
|             kwargs = {
 | |
|                 key: test_opts[opt][0],
 | |
|             }
 | |
|             env = {
 | |
|                 osc_lib_test_utils.opt2env(opt): test_opts[opt][0],
 | |
|             }
 | |
|             os.environ = env.copy()
 | |
|             self._assert_cloud_config_arg("", kwargs)
 | |
| 
 | |
| 
 | |
| class TestShellTokenAuthEnv(TestShell):
 | |
| 
 | |
|     def setUp(self):
 | |
|         super(TestShellTokenAuthEnv, self).setUp()
 | |
|         env = {
 | |
|             "OS_TOKEN": DEFAULT_TOKEN,
 | |
|             "OS_AUTH_URL": DEFAULT_AUTH_URL,
 | |
|         }
 | |
|         self.useFixture(osc_lib_test_utils.EnvFixture(env.copy()))
 | |
| 
 | |
|     def test_env(self):
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "token": DEFAULT_TOKEN,
 | |
|             "auth_url": DEFAULT_AUTH_URL,
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
|     def test_only_token(self):
 | |
|         flag = "--os-token xyzpdq"
 | |
|         kwargs = {
 | |
|             "token": "xyzpdq",
 | |
|             "auth_url": DEFAULT_AUTH_URL,
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
|     def test_only_auth_url(self):
 | |
|         flag = "--os-auth-url http://cloud.local:555"
 | |
|         kwargs = {
 | |
|             "token": DEFAULT_TOKEN,
 | |
|             "auth_url": "http://cloud.local:555",
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
|     def test_empty_auth(self):
 | |
|         os.environ = {}
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "token": '',
 | |
|             "auth_url": '',
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
| 
 | |
| class TestShellTokenEndpointAuthEnv(TestShell):
 | |
| 
 | |
|     def setUp(self):
 | |
|         super(TestShellTokenEndpointAuthEnv, self).setUp()
 | |
|         env = {
 | |
|             "OS_TOKEN": DEFAULT_TOKEN,
 | |
|             "OS_URL": DEFAULT_SERVICE_URL,
 | |
|         }
 | |
|         self.useFixture(osc_lib_test_utils.EnvFixture(env.copy()))
 | |
| 
 | |
|     def test_env(self):
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "token": DEFAULT_TOKEN,
 | |
|             "url": DEFAULT_SERVICE_URL,
 | |
|         }
 | |
|         self._assert_token_endpoint_auth(flag, kwargs)
 | |
| 
 | |
|     def test_only_token(self):
 | |
|         flag = "--os-token xyzpdq"
 | |
|         kwargs = {
 | |
|             "token": "xyzpdq",
 | |
|             "url": DEFAULT_SERVICE_URL,
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
|     def test_only_url(self):
 | |
|         flag = "--os-url http://cloud.local:555"
 | |
|         kwargs = {
 | |
|             "token": DEFAULT_TOKEN,
 | |
|             "url": "http://cloud.local:555",
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
|     def test_empty_auth(self):
 | |
|         os.environ = {}
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "token": '',
 | |
|             "url": '',
 | |
|         }
 | |
|         self._assert_token_auth(flag, kwargs)
 | |
| 
 | |
| 
 | |
| class TestShellCli(TestShell):
 | |
| 
 | |
|     def setUp(self):
 | |
|         super(TestShellCli, self).setUp()
 | |
|         env = {
 | |
|             "OS_COMPUTE_API_VERSION": DEFAULT_COMPUTE_API_VERSION,
 | |
|             "OS_IDENTITY_API_VERSION": DEFAULT_IDENTITY_API_VERSION,
 | |
|             "OS_IMAGE_API_VERSION": DEFAULT_IMAGE_API_VERSION,
 | |
|             "OS_VOLUME_API_VERSION": DEFAULT_VOLUME_API_VERSION,
 | |
|             "OS_NETWORK_API_VERSION": DEFAULT_NETWORK_API_VERSION,
 | |
|         }
 | |
|         self.useFixture(osc_lib_test_utils.EnvFixture(env.copy()))
 | |
| 
 | |
|     def test_default_env(self):
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "compute_api_version": DEFAULT_COMPUTE_API_VERSION,
 | |
|             "identity_api_version": DEFAULT_IDENTITY_API_VERSION,
 | |
|             "image_api_version": DEFAULT_IMAGE_API_VERSION,
 | |
|             "volume_api_version": DEFAULT_VOLUME_API_VERSION,
 | |
|             "network_api_version": DEFAULT_NETWORK_API_VERSION,
 | |
|         }
 | |
|         self._assert_cli(flag, kwargs)
 | |
| 
 | |
|     def test_empty_env(self):
 | |
|         os.environ = {}
 | |
|         flag = ""
 | |
|         kwargs = {
 | |
|             "compute_api_version": LIB_COMPUTE_API_VERSION,
 | |
|             "identity_api_version": LIB_IDENTITY_API_VERSION,
 | |
|             "image_api_version": LIB_IMAGE_API_VERSION,
 | |
|             "volume_api_version": LIB_VOLUME_API_VERSION,
 | |
|             "network_api_version": LIB_NETWORK_API_VERSION
 | |
|         }
 | |
|         self._assert_cli(flag, kwargs)
 | |
| 
 | |
| 
 | |
| class TestShellArgV(TestShell):
 | |
|     """Test the deferred help flag"""
 | |
| 
 | |
|     def test_shell_argv(self):
 | |
|         """Test argv decoding
 | |
| 
 | |
|         Python 2 does nothing with argv while Python 3 decodes it into
 | |
|         Unicode before we ever see it.  We manually decode when running
 | |
|         under Python 2 so verify that we get the right argv types.
 | |
| 
 | |
|         Use the argv supplied by the test runner so we get actual Python
 | |
|         runtime behaviour; we only need to check the type of argv[0]
 | |
|         which will alwyas be present.
 | |
|         """
 | |
| 
 | |
|         with mock.patch(
 | |
|                 self.shell_class_name + ".run",
 | |
|                 self.app,
 | |
|         ):
 | |
|             # Ensure type gets through unmolested through shell.main()
 | |
|             argv = sys.argv
 | |
|             shell.main(sys.argv)
 | |
|             self.assertEqual(type(argv[0]), type(self.app.call_args[0][0][0]))
 | |
| 
 | |
|             # When shell.main() gets sys.argv itself it should be decoded
 | |
|             shell.main()
 | |
|             self.assertEqual(type(u'x'), type(self.app.call_args[0][0][0]))
 |