def test_list_messages(self): cs = fakes.FakeClient(api_versions.APIVersion('3.3')) cs.messages.list() cs.assert_called('GET', '/messages')
def test_null_version(self): v = api_versions.APIVersion() self.assertFalse(v)
def test_get_string(self): v1_string = "3.23" v1 = api_versions.APIVersion(v1_string) self.assertEqual(v1_string, v1.get_string()) self.assertRaises(ValueError, api_versions.APIVersion().get_string)
class CinderClientTestCase(test.NoDBTestCase): """Used to test constructing a cinder client object at various versions.""" def setUp(self): super(CinderClientTestCase, self).setUp() cinder.reset_globals() self.ctxt = context.RequestContext('fake-user', 'fake-project') # Mock out the keystoneauth stuff. self.mock_session = mock.Mock(autospec=session.Session) load_session = mock.patch( 'keystoneauth1.loading.' 'load_session_from_conf_options', return_value=self.mock_session).start() self.addCleanup(load_session.stop) @mock.patch('cinderclient.client.get_volume_api_from_url', return_value='3') def test_create_v3_client_no_microversion(self, get_volume_api): """Tests that creating a v3 client, which is the default, and without specifying a microversion will default to 3.0 as the version to use. """ client = cinder.cinderclient(self.ctxt) self.assertEqual(cinder_api_versions.APIVersion('3.0'), client.api_version) get_volume_api.assert_called_once_with( self.mock_session.get_endpoint.return_value) @mock.patch( 'nova.volume.cinder._get_highest_client_server_version', # Fake the case that cinder is really old. return_value=cinder_api_versions.APIVersion('2.0')) @mock.patch('cinderclient.client.get_volume_api_from_url', return_value='3') def test_create_v3_client_with_microversion_too_new( self, get_volume_api, get_highest_version): """Tests that creating a v3 client and requesting a microversion that is either too new for the server (or client) to support raises an exception. """ self.assertRaises(exception.CinderAPIVersionNotAvailable, cinder.cinderclient, self.ctxt, microversion='3.44') get_volume_api.assert_called_once_with( self.mock_session.get_endpoint.return_value) get_highest_version.assert_called_once_with( self.ctxt, self.mock_session.get_endpoint.return_value) @mock.patch('nova.volume.cinder._get_highest_client_server_version', return_value=cinder_api_versions.APIVersion( cinder_api_versions.MAX_VERSION)) @mock.patch('cinderclient.client.get_volume_api_from_url', return_value='3') def test_create_v3_client_with_microversion_available( self, get_volume_api, get_highest_version): """Tests that creating a v3 client and requesting a microversion that is available in the server and supported by the client will result in creating a Client object with the requested microversion. """ client = cinder.cinderclient(self.ctxt, microversion='3.44') self.assertEqual(cinder_api_versions.APIVersion('3.44'), client.api_version) get_volume_api.assert_called_once_with( self.mock_session.get_endpoint.return_value) get_highest_version.assert_called_once_with( self.ctxt, self.mock_session.get_endpoint.return_value) @mock.patch('nova.volume.cinder._get_highest_client_server_version', new_callable=mock.NonCallableMock) # asserts not called @mock.patch('cinderclient.client.get_volume_api_from_url', return_value='3') def test_create_v3_client_with_microversion_skip_version_check( self, get_volume_api, get_highest_version): """Tests that creating a v3 client and requesting a microversion but asking to skip the version discovery check is honored. """ client = cinder.cinderclient(self.ctxt, microversion='3.44', skip_version_check=True) self.assertEqual(cinder_api_versions.APIVersion('3.44'), client.api_version) get_volume_api.assert_called_once_with( self.mock_session.get_endpoint.return_value) @mock.patch('nova.volume.cinder.LOG.error') @mock.patch.object(ks_loading, 'load_auth_from_conf_options') def test_load_auth_plugin_failed(self, mock_load_from_conf, mock_log_err): mock_load_from_conf.return_value = None self.assertRaises(cinder_exception.Unauthorized, cinder._load_auth_plugin, CONF) mock_log_err.assert_called() self.assertIn('The [cinder] section of your nova configuration file', mock_log_err.call_args[0][0]) @mock.patch('nova.volume.cinder._ADMIN_AUTH') def test_admin_context_without_token(self, mock_admin_auth): mock_admin_auth.return_value = '_FAKE_ADMIN_AUTH' admin_ctx = context.get_admin_context() params = cinder._get_cinderclient_parameters(admin_ctx) self.assertEqual(params[0], mock_admin_auth)
def test_api_version_is_major(self): headers = {} api_versions.update_headers(headers, api_versions.APIVersion("7.0")) self.assertEqual({}, headers)
def __init__(self, *args, **kwargs): self.api_version = kwargs.pop('api_version', None) self.api_version = self.api_version or api_versions.APIVersion() self.retries = kwargs.pop('retries', 0) self._logger = logging.getLogger(__name__) super(SessionClient, self).__init__(*args, **kwargs)
def run(self): """Load and document the current config options.""" cindershell = shell.OpenStackCinderShell() parser = cindershell.get_base_parser() api_version = api_versions.APIVersion(api_versions.MAX_VERSION) LOG.info('Generating CLI docs %s', api_version) cindershell.get_subcommand_parser(api_version, False, []) result = sm.ViewList() source = '<{}>'.format(__name__) result.append('.. _cinder_command_usage:', source) result.append('', source) result.append('cinder usage', source) result.append('------------', source) result.append('', source) result.append('.. code-block:: console', source) result.append('', source) result.append('', source) usage = self._get_usage_lines(parser.format_usage(), '<subcommand> ...') for line in usage: result.append(' {}'.format(line), source) result.append('', source) result.append('.. _cinder_command_options:', source) result.append('', source) result.append('Optional Arguments', source) result.append('~~~~~~~~~~~~~~~~~~', source) result.append('', source) # This accesses a private variable from argparse. That's a little # risky, but since this is just for the docs and not "production" code, # and since this variable hasn't changed in years, it's a calculated # risk to make this documentation generation easier. But if something # suddenly breaks, check here first. actions = sorted(parser._actions, key=lambda x: x.option_strings[0]) for action in actions: if action.help == '==SUPPRESS==': continue opts = ', '.join(action.option_strings) result.append('``{}``'.format(opts), source) result.append(' {}'.format(action.help), source) result.append('', source) result.append('', source) result.append('.. _cinder_commands:', source) result.append('', source) result.append('Commands', source) result.append('~~~~~~~~', source) result.append('', source) for cmd in cindershell.subcommands: if 'completion' in cmd: continue result.append('``{}``'.format(cmd), source) subcmd = cindershell.subcommands[cmd] description = self._format_description_lines(subcmd.description) result.append(' {}'.format(description[0]), source) result.append('', source) result.append('', source) result.append('.. _cinder_command_details:', source) result.append('', source) result.append('Command Details', source) result.append('---------------', source) result.append('', source) for cmd in cindershell.subcommands: if 'completion' in cmd: continue subcmd = cindershell.subcommands[cmd] result.append('.. _cinder{}:'.format(cmd), source) result.append('', source) result.append(subcmd.prog, source) result.append('~' * len(subcmd.prog), source) result.append('', source) result.append('.. code-block:: console', source) result.append('', source) usage = self._get_usage_lines(subcmd.format_usage()) for line in usage: result.append(' {}'.format(line), source) result.append('', source) description = self._format_description_lines(subcmd.description) result.append(description[0], source) result.append('', source) if len(subcmd._actions) == 0: continue positional = [] optional = [] for action in subcmd._actions: if len(action.option_strings): if (action.option_strings[0] != '-h' and action.help != '==SUPPRESS=='): optional.append(action) else: positional.append(action) if positional: result.append('**Positional arguments:**', source) result.append('', source) for action in positional: result.append('``{}``'.format(action.metavar), source) result.append(' {}'.format(action.help), source) result.append('', source) if optional: result.append('**Optional arguments:**', source) result.append('', source) for action in optional: result.append( '``{} {}``'.format(', '.join(action.option_strings), action.metavar), source) result.append(' {}'.format(action.help), source) result.append('', source) node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, result, node) return node.children
def test_null_version(self): v = api_versions.APIVersion() self.assertTrue(v.is_null())
def __init__(self, *args, **kwargs): self.api_version = kwargs.pop('api_version', None) self.api_version = self.api_version or api_versions.APIVersion() super(SessionClient, self).__init__(*args, **kwargs)
def test_get_messages(self): cs = fakes.FakeClient(api_versions.APIVersion('3.3')) fake_id = '1234' cs.messages.get(fake_id) cs.assert_called('GET', '/messages/%s' % fake_id)
def test_delete_messages(self): cs = fakes.FakeClient(api_versions.APIVersion('3.3')) fake_id = '1234' cs.messages.delete(fake_id) cs.assert_called('DELETE', '/messages/%s' % fake_id)
def test_list_messages_with_invalid_sort(self, sort_string): cs = fakes.FakeClient(api_versions.APIVersion('3.5')) self.assertRaises(ValueError, cs.messages.list, sort=sort_string)
def test_list_messages_with_filters(self, filter_string): cs = fakes.FakeClient(api_versions.APIVersion('3.5')) cs.messages.list(search_opts={filter_string: 'value'}) cs.assert_called('GET', '/messages?%s=value' % parse.quote(filter_string))
def test_list_messages_with_sort(self, sort_string): cs = fakes.FakeClient(api_versions.APIVersion('3.5')) cs.messages.list(sort=sort_string) cs.assert_called('GET', '/messages?sort=%s' % parse.quote(sort_string))
def get_highest_client_server_version(url, insecure=False, cacert=None): """Returns highest supported version by client and server as a string.""" min_server, max_server = get_server_version(url, insecure, cacert) max_client = api_versions.APIVersion(api_versions.MAX_VERSION) return min(max_server, max_client).get_string()
def __init__(self, username=None, api_key=None, project_id=None, auth_url='', insecure=False, timeout=None, tenant_id=None, proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', extensions=None, service_type='volumev2', service_name=None, volume_service_name=None, bypass_url=None, retries=None, http_log_debug=False, cacert=None, auth_system='keystone', auth_plugin=None, session=None, api_version=None, **kwargs): # FIXME(comstud): Rename the api_key argument above when we # know it's not being used as keyword argument password = api_key self.version = '2.0' self.limits = limits.LimitsManager(self) # extensions self.volumes = volumes.VolumeManager(self) self.volume_snapshots = volume_snapshots.SnapshotManager(self) self.volume_types = volume_types.VolumeTypeManager(self) self.volume_type_access = \ volume_type_access.VolumeTypeAccessManager(self) self.volume_encryption_types = \ volume_encryption_types.VolumeEncryptionTypeManager(self) self.qos_specs = qos_specs.QoSSpecsManager(self) self.quota_classes = quota_classes.QuotaClassSetManager(self) self.quotas = quotas.QuotaSetManager(self) self.backups = volume_backups.VolumeBackupManager(self) self.restores = volume_backups_restore.VolumeBackupRestoreManager(self) self.transfers = volume_transfers.VolumeTransferManager(self) self.services = services.ServiceManager(self) self.consistencygroups = consistencygroups.\ ConsistencygroupManager(self) self.cgsnapshots = cgsnapshots.CgsnapshotManager(self) self.availability_zones = \ availability_zones.AvailabilityZoneManager(self) self.pools = pools.PoolManager(self) self.capabilities = capabilities.CapabilitiesManager(self) self.api_version = api_version or api_versions.APIVersion(self.version) # Add in any extensions... if extensions: for extension in extensions: if extension.manager_class: setattr(self, extension.name, extension.manager_class(self)) self.client = client._construct_http_client( username=username, password=password, project_id=project_id, auth_url=auth_url, insecure=insecure, timeout=timeout, tenant_id=tenant_id, proxy_tenant_id=tenant_id, proxy_token=proxy_token, region_name=region_name, endpoint_type=endpoint_type, service_type=service_type, service_name=service_name, volume_service_name=volume_service_name, bypass_url=bypass_url, retries=retries, http_log_debug=http_log_debug, cacert=cacert, auth_system=auth_system, auth_plugin=auth_plugin, session=session, api_version=api_version, **kwargs)
def get_server_version(url, insecure=False, cacert=None): """Queries the server via the naked endpoint and gets version info. :param url: url of the cinder endpoint :param insecure: Explicitly allow client to perform "insecure" TLS (https) requests :param cacert: Specify a CA bundle file to use in verifying a TLS (https) server certificate :returns: APIVersion object for min and max version supported by the server """ min_version = "2.0" current_version = "2.0" logger = logging.getLogger(__name__) try: u = urllib.parse.urlparse(url) version_url = None # NOTE(andreykurilin): endpoint URL has at least 2 formats: # 1. The classic (legacy) endpoint: # http://{host}:{optional_port}/v{2 or 3}/{project-id} # http://{host}:{optional_port}/v{2 or 3} # 3. Under wsgi: # http://{host}:{optional_port}/volume/v{2 or 3} for ver in ['v2', 'v3']: if u.path.endswith(ver) or "/{0}/".format(ver) in u.path: path = u.path[:u.path.rfind(ver)] version_url = '%s://%s%s' % (u.scheme, u.netloc, path) break if not version_url: # NOTE(andreykurilin): probably, it is one of the next cases: # * https://volume.example.com/ # * https://example.com/volume # leave as is without cropping. version_url = url if insecure: verify_cert = False else: if cacert: verify_cert = cacert else: verify_cert = True response = requests.get(version_url, verify=verify_cert) data = json.loads(response.text) versions = data['versions'] for version in versions: if '3.' in version['version']: min_version = version['min_version'] current_version = version['version'] break else: # Set the values, but don't break out the loop here in case v3 # comes later min_version = '2.0' current_version = '2.0' except exceptions.ClientException as e: logger.warning("Error in server version query:%s\n" "Returning APIVersion 2.0", six.text_type(e.message)) return (api_versions.APIVersion(min_version), api_versions.APIVersion(current_version))
def main(self, argv): # Parse args once to find version and debug settings for filter in FILTER_CHECK: if filter in argv: self.check_duplicate_filters(argv, filter) break parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) api_version_input = True self.options = options do_help = ('help' in argv) or ('--help' in argv) or ('-h' in argv) or not argv api_version = self._validate_input_api_version(options) # build available subcommands based on version major_version_string = "%s" % api_version.ver_major self.extensions = client.discover_extensions(major_version_string) self._run_extension_hooks('__pre_parse_args__') subcommand_parser = self.get_subcommand_parser(api_version, do_help, args) self.parser = subcommand_parser if argv and len(argv) > 1 and '--help' in argv: argv = [x for x in argv if x != '--help'] if argv[0] in self.subcommands: self.subcommands[argv[0]].print_help() return 0 if options.help or not argv: subcommand_parser.print_help() return 0 argv = self._delimit_metadata_args(argv) args = subcommand_parser.parse_args(argv) self._run_extension_hooks('__post_parse_args__', args) # Short-circuit and deal with help right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 (os_username, os_password, os_project_name, os_auth_url, os_region_name, os_project_id, endpoint_type, service_type, service_name, volume_service_name, os_endpoint, cacert, os_auth_type) = (args.os_username, args.os_password, args.os_project_name, args.os_auth_url, args.os_region_name, args.os_project_id, args.os_endpoint_type, args.service_type, args.service_name, args.volume_service_name, args.os_endpoint, args.os_cacert, args.os_auth_type) auth_session = None if os_auth_type and os_auth_type != "keystone": auth_plugin = loading.load_auth_from_argparse_arguments( self.options) auth_session = loading.load_session_from_argparse_arguments( self.options, auth=auth_plugin) else: auth_plugin = None if not service_type: service_type = client.SERVICE_TYPES[major_version_string] # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. # V3 stuff project_info_provided = ((self.options.os_project_name and (self.options.os_project_domain_name or self.options.os_project_domain_id)) or self.options.os_project_id or self.options.os_project_name) # NOTE(e0ne): if auth_session exists it means auth plugin created # session and we don't need to check for password and other # authentification-related things. if not utils.isunauthenticated(args.func) and not auth_session: if not os_password: # No password, If we've got a tty, try prompting for it if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): # Check for Ctl-D try: os_password = getpass.getpass('OS Password: '******'t have a tty or the # user Ctl-D when prompted. if not os_password: raise exc.CommandError("You must provide a password " "through --os-password, " "env[OS_PASSWORD] " "or, prompted response.") if not project_info_provided: raise exc.CommandError( _("You must provide a project_id or project_name (with " "project_domain_name or project_domain_id) via " " --os-project-id (env[OS_PROJECT_ID])" " --os-project-name (env[OS_PROJECT_NAME])," " --os-project-domain-id " "(env[OS_PROJECT_DOMAIN_ID])" " --os-project-domain-name " "(env[OS_PROJECT_DOMAIN_NAME])")) if not os_auth_url: raise exc.CommandError( "You must provide an authentication URL " "through --os-auth-url or env[OS_AUTH_URL].") if not project_info_provided: raise exc.CommandError( _("You must provide a project_id or project_name (with " "project_domain_name or project_domain_id) via " " --os-project-id (env[OS_PROJECT_ID])" " --os-project-name (env[OS_PROJECT_NAME])," " --os-project-domain-id " "(env[OS_PROJECT_DOMAIN_ID])" " --os-project-domain-name " "(env[OS_PROJECT_DOMAIN_NAME])")) if not os_auth_url and not auth_plugin: raise exc.CommandError( "You must provide an authentication URL " "through --os-auth-url or env[OS_AUTH_URL].") if not auth_session: auth_session = self._get_keystone_session() insecure = self.options.insecure client_args = dict( region_name=os_region_name, tenant_id=os_project_id, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, volume_service_name=volume_service_name, os_endpoint=os_endpoint, retries=options.retries, http_log_debug=args.debug, insecure=insecure, cacert=cacert, auth_system=os_auth_type, auth_plugin=auth_plugin, session=auth_session, logger=self.ks_logger if auth_session else self.client_logger) self.cs = client.Client(api_version, os_username, os_password, os_project_name, os_auth_url, **client_args) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("OpenStack credentials are not valid.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user.") endpoint_api_version = None # Try to get the API version from the endpoint URL. If that fails fall # back to trying to use what the user specified via # --os-volume-api-version or with the OS_VOLUME_API_VERSION environment # variable. Fail safe is to use the default API setting. try: endpoint_api_version = \ self.cs.get_volume_api_version_from_endpoint() except exc.UnsupportedVersion: endpoint_api_version = options.os_volume_api_version if api_version_input: logger.warning( "Cannot determine the API version from " "the endpoint URL. Falling back to the " "user-specified version: %s", endpoint_api_version) else: logger.warning( "Cannot determine the API version from the " "endpoint URL or user input. Falling back " "to the default API version: %s", endpoint_api_version) API_MAX_VERSION = api_versions.APIVersion(api_versions.MAX_VERSION) if endpoint_api_version[0] == '3': disc_client = client.Client(API_MAX_VERSION, os_username, os_password, os_project_name, os_auth_url, **client_args) self.cs, discovered_version = self._discover_client( disc_client, api_version, args.os_endpoint_type, args.service_type, os_username, os_password, os_project_name, os_auth_url, client_args) if discovered_version < api_version: self.downgrade_warning(api_version, discovered_version) profile = osprofiler_profiler and options.profile if profile: osprofiler_profiler.init(options.profile) try: args.func(self.cs, args) finally: if profile: trace_id = osprofiler_profiler.get().get_base_id() print("Trace ID: %s" % trace_id) print("To display trace use next command:\n" "osprofiler trace show --html %s " % trace_id)
def __init__(self, user, password, projectid, auth_url=None, insecure=False, timeout=None, tenant_id=None, proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', service_type=None, service_name=None, volume_service_name=None, bypass_url=None, retries=None, http_log_debug=False, cacert=None, auth_system='keystone', auth_plugin=None, api_version=None, logger=None, user_domain_name='Default', project_domain_name='Default'): self.user = user self.password = password self.projectid = projectid self.tenant_id = tenant_id self.api_version = api_version or api_versions.APIVersion() if auth_system and auth_system != 'keystone' and not auth_plugin: raise exceptions.AuthSystemNotFound(auth_system) if not auth_url and auth_system and auth_system != 'keystone': auth_url = auth_plugin.get_auth_url() if not auth_url: raise exceptions.EndpointNotFound() self.auth_url = auth_url.rstrip('/') if auth_url else None self.version = 'v1' self.region_name = region_name self.endpoint_type = endpoint_type self.service_type = service_type self.service_name = service_name self.volume_service_name = volume_service_name self.bypass_url = bypass_url.rstrip('/') if bypass_url else bypass_url self.retries = int(retries or 0) self.http_log_debug = http_log_debug self.management_url = self.bypass_url or None self.auth_token = None self.proxy_token = proxy_token self.proxy_tenant_id = proxy_tenant_id self.timeout = timeout self.user_domain_name = user_domain_name self.project_domain_name = project_domain_name if insecure: self.verify_cert = False else: if cacert: self.verify_cert = cacert else: self.verify_cert = True self.auth_system = auth_system self.auth_plugin = auth_plugin self._logger = logger or logging.getLogger(__name__)
def test_volume_summary(self, all_tenants_input): all_tenants, url = all_tenants_input cs = fakes.FakeClient(api_versions.APIVersion('3.12')) cs.volumes.summary(all_tenants=all_tenants) cs.assert_called('GET', url)
def _get_highest_client_server_version(context, url): """Returns highest APIVersion supported version by client and server.""" min_server, max_server = _get_server_version(context, url) max_client = cinder_api_versions.APIVersion( cinder_api_versions.MAX_VERSION) return min(max_server, max_client)
def test_volume_list_manageable(self): cs = fakes.FakeClient(api_versions.APIVersion('3.8')) cs.volumes.list_manageable('host1', detailed=False) cs.assert_called('GET', '/manageable_volumes?host=host1')
def test_api_version_is_null(self): headers = {} api_versions.update_headers(headers, api_versions.APIVersion()) self.assertEqual({}, headers)
def test_snapshot_list_manageable_detailed(self): cs = fakes.FakeClient(api_versions.APIVersion('3.8')) cs.volume_snapshots.list_manageable('host1', detailed=True) cs.assert_called('GET', '/manageable_snapshots/detail?host=host1')
def _test_string(version, exp_major, exp_minor): v = api_versions.APIVersion(version) self.assertEqual(v.ver_major, exp_major) self.assertEqual(v.ver_minor, exp_minor)
def test_snapshot_list_with_metadata(self): cs = fakes.FakeClient(api_versions.APIVersion('3.22')) cs.volume_snapshots.list(search_opts={'metadata': {'key1': 'val1'}}) expected = ("/snapshots/detail?metadata=%s" % parse.quote_plus("{'key1': 'val1'}")) cs.assert_called('GET', expected)
def test_not_null_version(self): v = api_versions.APIVersion('1.1') self.assertTrue(v)
def test_list_with_image_metadata(self): cs = fakes.FakeClient(api_versions.APIVersion('3.0')) cs.volumes.list(search_opts={'glance_metadata': {'key1': 'val1'}}) expected = ("/volumes/detail?glance_metadata=%s" % parse.quote_plus("{'key1': 'val1'}")) cs.assert_called('GET', expected)
# # 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 ddt from cinderclient import api_versions from cinderclient.tests.unit import utils from cinderclient.tests.unit.v3 import fakes cs = fakes.FakeClient(api_versions.APIVersion('3.13')) @ddt.ddt class GroupsTest(utils.TestCase): def test_delete_group(self): expected = {'delete': {'delete-volumes': True}} v = cs.groups.list()[0] grp = v.delete(delete_volumes=True) self._assert_request_id(grp) cs.assert_called('POST', '/groups/1234/action', body=expected) grp = cs.groups.delete('1234', delete_volumes=True) self._assert_request_id(grp) cs.assert_called('POST', '/groups/1234/action', body=expected) grp = cs.groups.delete(v, delete_volumes=True) self._assert_request_id(grp)
def test_api_version(self): version = api_versions.APIVersion('3.1') api = client.Client(api_version=version) manager = test_utils.FakeManagerWithApi(api) r1 = base.Resource(manager, {'id': 1}) self.assertEqual(version, r1.api_version)