diff options
Diffstat (limited to 'functional/tests/identity/v3')
| -rw-r--r-- | functional/tests/identity/v3/__init__.py | 0 | ||||
| -rw-r--r-- | functional/tests/identity/v3/common.py | 289 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_catalog.py | 45 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_domain.py | 69 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_endpoint.py | 67 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_group.py | 178 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_idp.py | 61 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_project.py | 113 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_region.py | 70 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_role.py | 145 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_service.py | 71 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_service_provider.py | 61 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_token.py | 21 | ||||
| -rw-r--r-- | functional/tests/identity/v3/test_user.py | 101 |
14 files changed, 0 insertions, 1291 deletions
diff --git a/functional/tests/identity/v3/__init__.py b/functional/tests/identity/v3/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/functional/tests/identity/v3/__init__.py +++ /dev/null diff --git a/functional/tests/identity/v3/common.py b/functional/tests/identity/v3/common.py deleted file mode 100644 index 47019c5f..00000000 --- a/functional/tests/identity/v3/common.py +++ /dev/null @@ -1,289 +0,0 @@ -# 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 os - -from tempest.lib.common.utils import data_utils - -from functional.common import test - - -BASIC_LIST_HEADERS = ['ID', 'Name'] - - -class IdentityTests(test.TestCase): - """Functional tests for Identity commands. """ - - DOMAIN_FIELDS = ['description', 'enabled', 'id', 'name', 'links'] - GROUP_FIELDS = ['description', 'domain_id', 'id', 'name', 'links'] - TOKEN_FIELDS = ['expires', 'id', 'project_id', 'user_id'] - USER_FIELDS = ['email', 'enabled', 'id', 'name', 'name', - 'domain_id', 'default_project_id', 'description', - 'password_expires_at'] - PROJECT_FIELDS = ['description', 'id', 'domain_id', 'is_domain', - 'enabled', 'name', 'parent_id', 'links'] - ROLE_FIELDS = ['id', 'name', 'links', 'domain_id'] - SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description'] - REGION_FIELDS = ['description', 'enabled', 'parent_region', 'region'] - ENDPOINT_FIELDS = ['id', 'region', 'region_id', 'service_id', - 'service_name', 'service_type', 'enabled', - 'interface', 'url'] - - REGION_LIST_HEADERS = ['Region', 'Parent Region', 'Description'] - ENDPOINT_LIST_HEADERS = ['ID', 'Region', 'Service Name', 'Service Type', - 'Enabled', 'Interface', 'URL'] - - IDENTITY_PROVIDER_FIELDS = ['description', 'enabled', 'id', 'remote_ids'] - IDENTITY_PROVIDER_LIST_HEADERS = ['ID', 'Enabled', 'Description'] - - SERVICE_PROVIDER_FIELDS = ['auth_url', 'description', 'enabled', - 'id', 'relay_state_prefix', 'sp_url'] - SERVICE_PROVIDER_LIST_HEADERS = ['ID', 'Enabled', 'Description', - 'Auth URL'] - - @classmethod - def setUpClass(cls): - # prepare v3 env - os.environ['OS_IDENTITY_API_VERSION'] = '3' - auth_url = os.environ.get('OS_AUTH_URL') - auth_url = auth_url.replace('v2.0', 'v3') - os.environ['OS_AUTH_URL'] = auth_url - - # create dummy domain - cls.domain_name = data_utils.rand_name('TestDomain') - cls.domain_description = data_utils.rand_name('description') - cls.openstack( - 'domain create ' - '--description %(description)s ' - '--enable ' - '%(name)s' % {'description': cls.domain_description, - 'name': cls.domain_name}) - - # create dummy project - cls.project_name = data_utils.rand_name('TestProject') - cls.project_description = data_utils.rand_name('description') - cls.openstack( - 'project create ' - '--domain %(domain)s ' - '--description %(description)s ' - '--enable ' - '%(name)s' % {'domain': cls.domain_name, - 'description': cls.project_description, - 'name': cls.project_name}) - - @classmethod - def tearDownClass(cls): - # delete dummy project - cls.openstack('project delete %s' % cls.project_name) - # disable and delete dummy domain - cls.openstack('domain set --disable %s' % cls.domain_name) - cls.openstack('domain delete %s' % cls.domain_name) - - def _create_dummy_user(self, add_clean_up=True): - username = data_utils.rand_name('TestUser') - password = data_utils.rand_name('password') - email = data_utils.rand_name() + '@example.com' - description = data_utils.rand_name('description') - raw_output = self.openstack( - 'user create ' - '--domain %(domain)s ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--password %(password)s ' - '--email %(email)s ' - '--description %(description)s ' - '--enable ' - '%(name)s' % {'domain': self.domain_name, - 'project': self.project_name, - 'project_domain': self.domain_name, - 'email': email, - 'password': password, - 'description': description, - 'name': username}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'user delete %s' % self.parse_show_as_object(raw_output)['id']) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.USER_FIELDS) - return username - - def _create_dummy_role(self, add_clean_up=True): - role_name = data_utils.rand_name('TestRole') - raw_output = self.openstack('role create %s' % role_name) - role = self.parse_show_as_object(raw_output) - if add_clean_up: - self.addCleanup( - self.openstack, - 'role delete %s' % role['id']) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.ROLE_FIELDS) - self.assertEqual(role_name, role['name']) - return role_name - - def _create_dummy_group(self, add_clean_up=True): - group_name = data_utils.rand_name('TestGroup') - description = data_utils.rand_name('description') - raw_output = self.openstack( - 'group create ' - '--domain %(domain)s ' - '--description %(description)s ' - '%(name)s' % {'domain': self.domain_name, - 'description': description, - 'name': group_name}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'group delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': group_name}) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.GROUP_FIELDS) - return group_name - - def _create_dummy_domain(self, add_clean_up=True): - domain_name = data_utils.rand_name('TestDomain') - domain_description = data_utils.rand_name('description') - self.openstack( - 'domain create ' - '--description %(description)s ' - '--enable %(name)s' % {'description': domain_description, - 'name': domain_name}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'domain delete %s' % domain_name - ) - self.addCleanup( - self.openstack, - 'domain set --disable %s' % domain_name - ) - return domain_name - - def _create_dummy_project(self, add_clean_up=True): - project_name = data_utils.rand_name('TestProject') - project_description = data_utils.rand_name('description') - self.openstack( - 'project create ' - '--domain %(domain)s ' - '--description %(description)s ' - '--enable %(name)s' % {'domain': self.domain_name, - 'description': project_description, - 'name': project_name}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'project delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': project_name}) - return project_name - - def _create_dummy_region(self, parent_region=None, add_clean_up=True): - region_id = data_utils.rand_name('TestRegion') - description = data_utils.rand_name('description') - parent_region_arg = '' - if parent_region is not None: - parent_region_arg = '--parent-region %s' % parent_region - raw_output = self.openstack( - 'region create ' - '%(parent_region_arg)s ' - '--description %(description)s ' - '%(id)s' % {'parent_region_arg': parent_region_arg, - 'description': description, - 'id': region_id}) - if add_clean_up: - self.addCleanup(self.openstack, - 'region delete %s' % region_id) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.REGION_FIELDS) - return region_id - - def _create_dummy_service(self, add_clean_up=True): - service_name = data_utils.rand_name('TestService') - description = data_utils.rand_name('description') - type_name = data_utils.rand_name('TestType') - raw_output = self.openstack( - 'service create ' - '--name %(name)s ' - '--description %(description)s ' - '--enable ' - '%(type)s' % {'name': service_name, - 'description': description, - 'type': type_name}) - if add_clean_up: - service = self.parse_show_as_object(raw_output) - self.addCleanup(self.openstack, - 'service delete %s' % service['id']) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.SERVICE_FIELDS) - return service_name - - def _create_dummy_endpoint(self, interface='public', add_clean_up=True): - region_id = self._create_dummy_region() - service_name = self._create_dummy_service() - endpoint_url = data_utils.rand_url() - raw_output = self.openstack( - 'endpoint create ' - '--region %(region)s ' - '--enable ' - '%(service)s ' - '%(interface)s ' - '%(url)s' % {'region': region_id, - 'service': service_name, - 'interface': interface, - 'url': endpoint_url}) - endpoint = self.parse_show_as_object(raw_output) - if add_clean_up: - self.addCleanup( - self.openstack, - 'endpoint delete %s' % endpoint['id']) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.ENDPOINT_FIELDS) - return endpoint['id'] - - def _create_dummy_idp(self, add_clean_up=True): - identity_provider = data_utils.rand_name('IdentityProvider') - description = data_utils.rand_name('description') - raw_output = self.openstack( - 'identity provider create ' - ' %(name)s ' - '--description %(description)s ' - '--enable ' % {'name': identity_provider, - 'description': description}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'identity provider delete %s' % identity_provider) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.IDENTITY_PROVIDER_FIELDS) - return identity_provider - - def _create_dummy_sp(self, add_clean_up=True): - service_provider = data_utils.rand_name('ServiceProvider') - description = data_utils.rand_name('description') - raw_output = self.openstack( - 'service provider create ' - ' %(name)s ' - '--description %(description)s ' - '--auth-url https://sp.example.com:35357 ' - '--service-provider-url https://sp.example.com:5000 ' - '--enable ' % {'name': service_provider, - 'description': description}) - if add_clean_up: - self.addCleanup( - self.openstack, - 'service provider delete %s' % service_provider) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.SERVICE_PROVIDER_FIELDS) - return service_provider diff --git a/functional/tests/identity/v3/test_catalog.py b/functional/tests/identity/v3/test_catalog.py deleted file mode 100644 index e33876b0..00000000 --- a/functional/tests/identity/v3/test_catalog.py +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -from functional.tests.identity.v3 import common - - -class CatalogTests(common.IdentityTests): - - def test_catalog_list(self): - raw_output = self.openstack('catalog list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, ['Name', 'Type', 'Endpoints']) - - def test_catalog_show(self): - """test catalog show command - - The output example: - +-----------+----------------------------------------+ - | Field | Value | - +-----------+----------------------------------------+ - | endpoints | test1 | - | | public: http://localhost:5000/v2.0 | - | | test1 | - | | internal: http://localhost:5000/v2.0 | - | | test1 | - | | admin: http://localhost:35357/v2.0 | - | | | - | id | e1e68b5ba21a43a39ff1cf58e736c3aa | - | name | keystone | - | type | identity | - +-----------+----------------------------------------+ - """ - raw_output = self.openstack('catalog show %s' % 'identity') - items = self.parse_show(raw_output) - # items may have multiple endpoint urls with empty key - self.assert_show_fields(items, ['endpoints', 'name', 'type', '', 'id']) diff --git a/functional/tests/identity/v3/test_domain.py b/functional/tests/identity/v3/test_domain.py deleted file mode 100644 index 3f514b58..00000000 --- a/functional/tests/identity/v3/test_domain.py +++ /dev/null @@ -1,69 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from functional.tests.identity.v3 import common - - -class DomainTests(common.IdentityTests): - - def test_domain_create(self): - domain_name = data_utils.rand_name('TestDomain') - raw_output = self.openstack('domain create %s' % domain_name) - # disable domain first before deleting it - self.addCleanup(self.openstack, - 'domain delete %s' % domain_name) - self.addCleanup(self.openstack, - 'domain set --disable %s' % domain_name) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.DOMAIN_FIELDS) - - def test_domain_list(self): - self._create_dummy_domain() - raw_output = self.openstack('domain list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - - def test_domain_delete(self): - domain_name = self._create_dummy_domain(add_clean_up=False) - # cannot delete enabled domain, disable it first - raw_output = self.openstack('domain set --disable %s' % domain_name) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('domain delete %s' % domain_name) - self.assertEqual(0, len(raw_output)) - - def test_domain_multi_delete(self): - domain_1 = self._create_dummy_domain(add_clean_up=False) - domain_2 = self._create_dummy_domain(add_clean_up=False) - # cannot delete enabled domain, disable it first - raw_output = self.openstack('domain set --disable %s' % domain_1) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('domain set --disable %s' % domain_2) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack( - 'domain delete %s %s' % (domain_1, domain_2)) - self.assertEqual(0, len(raw_output)) - - def test_domain_delete_failure(self): - domain_name = self._create_dummy_domain() - # cannot delete enabled domain - self.assertRaises(exceptions.CommandFailed, - self.openstack, - 'domain delete %s' % domain_name) - - def test_domain_show(self): - domain_name = self._create_dummy_domain() - raw_output = self.openstack('domain show %s' % domain_name) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.DOMAIN_FIELDS) diff --git a/functional/tests/identity/v3/test_endpoint.py b/functional/tests/identity/v3/test_endpoint.py deleted file mode 100644 index e0afab23..00000000 --- a/functional/tests/identity/v3/test_endpoint.py +++ /dev/null @@ -1,67 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class EndpointTests(common.IdentityTests): - - def test_endpoint_create(self): - self._create_dummy_endpoint(interface='public') - self._create_dummy_endpoint(interface='admin') - self._create_dummy_endpoint(interface='internal') - - def test_endpoint_delete(self): - endpoint_id = self._create_dummy_endpoint(add_clean_up=False) - raw_output = self.openstack( - 'endpoint delete %s' % endpoint_id) - self.assertEqual(0, len(raw_output)) - - def test_endpoint_multi_delete(self): - endpoint_1 = self._create_dummy_endpoint(add_clean_up=False) - endpoint_2 = self._create_dummy_endpoint(add_clean_up=False) - raw_output = self.openstack( - 'endpoint delete %s %s' % (endpoint_1, endpoint_2)) - self.assertEqual(0, len(raw_output)) - - def test_endpoint_list(self): - endpoint_id = self._create_dummy_endpoint() - raw_output = self.openstack('endpoint list') - self.assertIn(endpoint_id, raw_output) - items = self.parse_listing(raw_output) - self.assert_table_structure(items, self.ENDPOINT_LIST_HEADERS) - - def test_endpoint_set(self): - endpoint_id = self._create_dummy_endpoint() - new_endpoint_url = data_utils.rand_url() - raw_output = self.openstack( - 'endpoint set ' - '--interface %(interface)s ' - '--url %(url)s ' - '--disable ' - '%(endpoint_id)s' % {'interface': 'admin', - 'url': new_endpoint_url, - 'endpoint_id': endpoint_id}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('endpoint show %s' % endpoint_id) - endpoint = self.parse_show_as_object(raw_output) - self.assertEqual('admin', endpoint['interface']) - self.assertEqual(new_endpoint_url, endpoint['url']) - self.assertEqual('False', endpoint['enabled']) - - def test_endpoint_show(self): - endpoint_id = self._create_dummy_endpoint() - raw_output = self.openstack('endpoint show %s' % endpoint_id) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.ENDPOINT_FIELDS) diff --git a/functional/tests/identity/v3/test_group.py b/functional/tests/identity/v3/test_group.py deleted file mode 100644 index 35075698..00000000 --- a/functional/tests/identity/v3/test_group.py +++ /dev/null @@ -1,178 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class GroupTests(common.IdentityTests): - - def test_group_create(self): - self._create_dummy_group() - - def test_group_list(self): - group_name = self._create_dummy_group() - raw_output = self.openstack('group list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - self.assertIn(group_name, raw_output) - - def test_group_list_with_domain(self): - group_name = self._create_dummy_group() - raw_output = self.openstack( - 'group list --domain %s' % self.domain_name) - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - self.assertIn(group_name, raw_output) - - def test_group_delete(self): - group_name = self._create_dummy_group(add_clean_up=False) - raw_output = self.openstack( - 'group delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': group_name}) - self.assertEqual(0, len(raw_output)) - - def test_group_show(self): - group_name = self._create_dummy_group() - raw_output = self.openstack( - 'group show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': group_name}) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.GROUP_FIELDS) - - def test_group_set(self): - group_name = self._create_dummy_group() - new_group_name = data_utils.rand_name('NewTestGroup') - raw_output = self.openstack( - 'group set ' - '--domain %(domain)s ' - '--name %(new_group)s ' - '%(group)s' % {'domain': self.domain_name, - 'new_group': new_group_name, - 'group': group_name}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack( - 'group show ' - '--domain %(domain)s ' - '%(group)s' % {'domain': self.domain_name, - 'group': new_group_name}) - group = self.parse_show_as_object(raw_output) - self.assertEqual(new_group_name, group['name']) - # reset group name to make sure it will be cleaned up - raw_output = self.openstack( - 'group set ' - '--domain %(domain)s ' - '--name %(new_group)s ' - '%(group)s' % {'domain': self.domain_name, - 'new_group': group_name, - 'group': new_group_name}) - self.assertEqual(0, len(raw_output)) - - def test_group_add_user(self): - group_name = self._create_dummy_group() - username = self._create_dummy_user() - raw_output = self.openstack( - 'group add user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.addCleanup( - self.openstack, - 'group remove user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.assertEqual( - '%(user)s added to group %(group)s\n' % {'user': username, - 'group': group_name}, - raw_output - ) - - def test_group_contains_user(self): - group_name = self._create_dummy_group() - username = self._create_dummy_user() - raw_output = self.openstack( - 'group add user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.addCleanup( - self.openstack, - 'group remove user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.assertEqual( - '%(user)s added to group %(group)s\n' % {'user': username, - 'group': group_name}, - raw_output - ) - raw_output = self.openstack( - 'group contains user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.assertEqual( - '%(user)s in group %(group)s\n' % {'user': username, - 'group': group_name}, - raw_output) - - def test_group_remove_user(self): - group_name = self._create_dummy_group() - username = self._create_dummy_user() - add_raw_output = self.openstack( - 'group add user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - remove_raw_output = self.openstack( - 'group remove user ' - '--group-domain %(group_domain)s ' - '--user-domain %(user_domain)s ' - '%(group)s %(user)s' % {'group_domain': self.domain_name, - 'user_domain': self.domain_name, - 'group': group_name, - 'user': username}) - self.assertEqual( - '%(user)s added to group %(group)s\n' % {'user': username, - 'group': group_name}, - add_raw_output - ) - self.assertEqual( - '%(user)s removed from ' - 'group %(group)s\n' % {'user': username, - 'group': group_name}, - remove_raw_output - ) diff --git a/functional/tests/identity/v3/test_idp.py b/functional/tests/identity/v3/test_idp.py deleted file mode 100644 index bc9690f7..00000000 --- a/functional/tests/identity/v3/test_idp.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -from functional.tests.identity.v3 import common -from tempest.lib.common.utils import data_utils - - -class IdentityProviderTests(common.IdentityTests): - # Introduce functional test case for command 'Identity Provider' - - def test_idp_create(self): - self._create_dummy_idp() - - def test_idp_delete(self): - identity_provider = self._create_dummy_idp(add_clean_up=False) - raw_output = self.openstack('identity provider delete %s' - % identity_provider) - self.assertEqual(0, len(raw_output)) - - def test_idp_multi_delete(self): - idp_1 = self._create_dummy_idp(add_clean_up=False) - idp_2 = self._create_dummy_idp(add_clean_up=False) - raw_output = self.openstack( - 'identity provider delete %s %s' % (idp_1, idp_2)) - self.assertEqual(0, len(raw_output)) - - def test_idp_show(self): - identity_provider = self._create_dummy_idp(add_clean_up=True) - raw_output = self.openstack('identity provider show %s' - % identity_provider) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.IDENTITY_PROVIDER_FIELDS) - - def test_idp_list(self): - self._create_dummy_idp(add_clean_up=True) - raw_output = self.openstack('identity provider list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, self.IDENTITY_PROVIDER_LIST_HEADERS) - - def test_idp_set(self): - identity_provider = self._create_dummy_idp(add_clean_up=True) - new_remoteid = data_utils.rand_name('newRemoteId') - raw_output = self.openstack('identity provider set ' - '%(identity-provider)s ' - '--remote-id %(remote-id)s ' - % {'identity-provider': identity_provider, - 'remote-id': new_remoteid}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('identity provider show %s' - % identity_provider) - updated_value = self.parse_show_as_object(raw_output) - self.assertIn(new_remoteid, updated_value['remote_ids']) diff --git a/functional/tests/identity/v3/test_project.py b/functional/tests/identity/v3/test_project.py deleted file mode 100644 index a27c58fb..00000000 --- a/functional/tests/identity/v3/test_project.py +++ /dev/null @@ -1,113 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class ProjectTests(common.IdentityTests): - - def test_project_create(self): - project_name = data_utils.rand_name('TestProject') - description = data_utils.rand_name('description') - raw_output = self.openstack( - 'project create ' - '--domain %(domain)s ' - '--description %(description)s ' - '--enable ' - '--property k1=v1 ' - '--property k2=v2 ' - '%(name)s' % {'domain': self.domain_name, - 'description': description, - 'name': project_name}) - self.addCleanup( - self.openstack, - 'project delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': project_name} - ) - items = self.parse_show(raw_output) - show_fields = list(self.PROJECT_FIELDS) - show_fields.extend(['k1', 'k2']) - self.assert_show_fields(items, show_fields) - project = self.parse_show_as_object(raw_output) - self.assertEqual('v1', project['k1']) - self.assertEqual('v2', project['k2']) - - def test_project_delete(self): - project_name = self._create_dummy_project(add_clean_up=False) - raw_output = self.openstack( - 'project delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': project_name}) - self.assertEqual(0, len(raw_output)) - - def test_project_list(self): - raw_output = self.openstack('project list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - - def test_project_list_with_domain(self): - project_name = self._create_dummy_project() - raw_output = self.openstack( - 'project list --domain %s' % self.domain_name) - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - self.assertIn(project_name, raw_output) - self.assertTrue(len(items) > 0) - - def test_project_set(self): - project_name = self._create_dummy_project() - new_project_name = data_utils.rand_name('NewTestProject') - raw_output = self.openstack( - 'project set ' - '--name %(new_name)s ' - '--disable ' - '--property k0=v0 ' - '%(name)s' % {'new_name': new_project_name, - 'domain': self.domain_name, - 'name': project_name}) - self.assertEqual(0, len(raw_output)) - # check project details - raw_output = self.openstack( - 'project show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': new_project_name} - ) - items = self.parse_show(raw_output) - fields = list(self.PROJECT_FIELDS) - fields.extend(['k0']) - self.assert_show_fields(items, fields) - project = self.parse_show_as_object(raw_output) - self.assertEqual(new_project_name, project['name']) - self.assertEqual('False', project['enabled']) - self.assertEqual('v0', project['k0']) - # reset project to make sure it will be cleaned up - self.openstack( - 'project set ' - '--name %(new_name)s ' - '--enable ' - '%(name)s' % {'new_name': project_name, - 'name': new_project_name}) - - def test_project_show(self): - raw_output = self.openstack( - 'project show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': self.project_name}) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.PROJECT_FIELDS) diff --git a/functional/tests/identity/v3/test_region.py b/functional/tests/identity/v3/test_region.py deleted file mode 100644 index 2ebc0e59..00000000 --- a/functional/tests/identity/v3/test_region.py +++ /dev/null @@ -1,70 +0,0 @@ -# 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. - -from functional.tests.identity.v3 import common - - -class RegionTests(common.IdentityTests): - - def test_region_create(self): - self._create_dummy_region() - - def test_region_create_with_parent_region(self): - parent_region_id = self._create_dummy_region() - self._create_dummy_region(parent_region=parent_region_id) - - def test_region_delete(self): - region_id = self._create_dummy_region(add_clean_up=False) - raw_output = self.openstack('region delete %s' % region_id) - self.assertEqual(0, len(raw_output)) - - def test_region_multi_delete(self): - region_1 = self._create_dummy_region(add_clean_up=False) - region_2 = self._create_dummy_region(add_clean_up=False) - raw_output = self.openstack( - 'region delete %s %s' % (region_1, region_2)) - self.assertEqual(0, len(raw_output)) - - def test_region_list(self): - raw_output = self.openstack('region list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, self.REGION_LIST_HEADERS) - - def test_region_set(self): - # prepare region with parent-region - parent_region_id = self._create_dummy_region() - new_parent_region_id = self._create_dummy_region() - region_id = self._create_dummy_region(parent_region_id) - # check region details - raw_output = self.openstack('region show %s' % region_id) - region = self.parse_show_as_object(raw_output) - self.assertEqual(parent_region_id, region['parent_region']) - self.assertEqual(region_id, region['region']) - # update parent-region - raw_output = self.openstack( - 'region set ' - '--parent-region %(parent_region)s ' - '%(region)s' % {'parent_region': new_parent_region_id, - 'region': region_id}) - self.assertEqual(0, len(raw_output)) - # check updated region details - raw_output = self.openstack('region show %s' % region_id) - region = self.parse_show_as_object(raw_output) - self.assertEqual(new_parent_region_id, region['parent_region']) - self.assertEqual(region_id, region['region']) - - def test_region_show(self): - region_id = self._create_dummy_region() - raw_output = self.openstack('region show %s' % region_id) - region = self.parse_show_as_object(raw_output) - self.assertEqual(region_id, region['region']) - self.assertEqual('None', region['parent_region']) diff --git a/functional/tests/identity/v3/test_role.py b/functional/tests/identity/v3/test_role.py deleted file mode 100644 index 60aaf3f4..00000000 --- a/functional/tests/identity/v3/test_role.py +++ /dev/null @@ -1,145 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class RoleTests(common.IdentityTests): - - def test_role_create(self): - self._create_dummy_role() - - def test_role_delete(self): - role_name = self._create_dummy_role(add_clean_up=False) - raw_output = self.openstack('role delete %s' % role_name) - self.assertEqual(0, len(raw_output)) - - def test_role_list(self): - self._create_dummy_role() - raw_output = self.openstack('role list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - - def test_role_list_with_user_project(self): - role_name = self._create_dummy_role() - username = self._create_dummy_user() - raw_output = self.openstack( - 'role add ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - self.addCleanup( - self.openstack, - 'role remove ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack( - 'role list ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name}) - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - self.assertEqual(1, len(items)) - - def test_role_show(self): - role_name = self._create_dummy_role() - raw_output = self.openstack('role show %s' % role_name) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.ROLE_FIELDS) - - def test_role_set(self): - role_name = self._create_dummy_role() - new_role_name = data_utils.rand_name('NewTestRole') - raw_output = self.openstack( - 'role set --name %s %s' % (new_role_name, role_name)) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('role show %s' % new_role_name) - role = self.parse_show_as_object(raw_output) - self.assertEqual(new_role_name, role['name']) - - def test_role_add(self): - role_name = self._create_dummy_role() - username = self._create_dummy_user() - raw_output = self.openstack( - 'role add ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - self.addCleanup( - self.openstack, - 'role remove ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - self.assertEqual(0, len(raw_output)) - - def test_role_remove(self): - role_name = self._create_dummy_role() - username = self._create_dummy_user() - add_raw_output = self.openstack( - 'role add ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - remove_raw_output = self.openstack( - 'role remove ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '--user %(user)s ' - '--user-domain %(user_domain)s ' - '%(role)s' % {'project': self.project_name, - 'project_domain': self.domain_name, - 'user': username, - 'user_domain': self.domain_name, - 'role': role_name}) - self.assertEqual(0, len(add_raw_output)) - self.assertEqual(0, len(remove_raw_output)) diff --git a/functional/tests/identity/v3/test_service.py b/functional/tests/identity/v3/test_service.py deleted file mode 100644 index 79a63dc8..00000000 --- a/functional/tests/identity/v3/test_service.py +++ /dev/null @@ -1,71 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class ServiceTests(common.IdentityTests): - - def test_service_create(self): - self._create_dummy_service() - - def test_service_delete(self): - service_name = self._create_dummy_service(add_clean_up=False) - raw_output = self.openstack('service delete %s' % service_name) - self.assertEqual(0, len(raw_output)) - - def test_service_multi_delete(self): - service_1 = self._create_dummy_service(add_clean_up=False) - service_2 = self._create_dummy_service(add_clean_up=False) - raw_output = self.openstack( - 'service delete %s %s' % (service_1, service_2)) - self.assertEqual(0, len(raw_output)) - - def test_service_list(self): - self._create_dummy_service() - raw_output = self.openstack('service list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - - def test_service_set(self): - service_name = self._create_dummy_service() - # set service - new_service_name = data_utils.rand_name('NewTestService') - new_service_description = data_utils.rand_name('description') - new_service_type = data_utils.rand_name('NewTestType') - raw_output = self.openstack( - 'service set ' - '--type %(type)s ' - '--name %(name)s ' - '--description %(description)s ' - '--disable ' - '%(service)s' % {'type': new_service_type, - 'name': new_service_name, - 'description': new_service_description, - 'service': service_name}) - self.assertEqual(0, len(raw_output)) - # get service details - raw_output = self.openstack('service show %s' % new_service_name) - # assert service details - service = self.parse_show_as_object(raw_output) - self.assertEqual(new_service_type, service['type']) - self.assertEqual(new_service_name, service['name']) - self.assertEqual(new_service_description, service['description']) - - def test_service_show(self): - service_name = self._create_dummy_service() - raw_output = self.openstack( - 'service show %s' % service_name) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.SERVICE_FIELDS) diff --git a/functional/tests/identity/v3/test_service_provider.py b/functional/tests/identity/v3/test_service_provider.py deleted file mode 100644 index 458c2ae6..00000000 --- a/functional/tests/identity/v3/test_service_provider.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -from functional.tests.identity.v3 import common -from tempest.lib.common.utils import data_utils - - -class ServiceProviderTests(common.IdentityTests): - # Introduce functional test cases for command 'Service Provider' - - def test_sp_create(self): - self._create_dummy_sp(add_clean_up=True) - - def test_sp_delete(self): - service_provider = self._create_dummy_sp(add_clean_up=False) - raw_output = self.openstack('service provider delete %s' - % service_provider) - self.assertEqual(0, len(raw_output)) - - def test_sp_multi_delete(self): - sp1 = self._create_dummy_sp(add_clean_up=False) - sp2 = self._create_dummy_sp(add_clean_up=False) - raw_output = self.openstack( - 'service provider delete %s %s' % (sp1, sp2)) - self.assertEqual(0, len(raw_output)) - - def test_sp_show(self): - service_provider = self._create_dummy_sp(add_clean_up=True) - raw_output = self.openstack('service provider show %s' - % service_provider) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.SERVICE_PROVIDER_FIELDS) - - def test_sp_list(self): - self._create_dummy_sp(add_clean_up=True) - raw_output = self.openstack('service provider list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, self.SERVICE_PROVIDER_LIST_HEADERS) - - def test_sp_set(self): - service_provider = self._create_dummy_sp(add_clean_up=True) - new_description = data_utils.rand_name('newDescription') - raw_output = self.openstack('service provider set ' - '%(service-provider)s ' - '--description %(description)s ' - % {'service-provider': service_provider, - 'description': new_description}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('service provider show %s' - % service_provider) - updated_value = self.parse_show_as_object(raw_output) - self.assertIn(new_description, updated_value['description']) diff --git a/functional/tests/identity/v3/test_token.py b/functional/tests/identity/v3/test_token.py deleted file mode 100644 index d8d3f43d..00000000 --- a/functional/tests/identity/v3/test_token.py +++ /dev/null @@ -1,21 +0,0 @@ -# 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. - -from functional.tests.identity.v3 import common - - -class TokenTests(common.IdentityTests): - - def test_token_issue(self): - raw_output = self.openstack('token issue') - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.TOKEN_FIELDS) diff --git a/functional/tests/identity/v3/test_user.py b/functional/tests/identity/v3/test_user.py deleted file mode 100644 index f3657064..00000000 --- a/functional/tests/identity/v3/test_user.py +++ /dev/null @@ -1,101 +0,0 @@ -# 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. - -from tempest.lib.common.utils import data_utils - -from functional.tests.identity.v3 import common - - -class UserTests(common.IdentityTests): - - def test_user_create(self): - self._create_dummy_user() - - def test_user_delete(self): - username = self._create_dummy_user(add_clean_up=False) - raw_output = self.openstack('user delete ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': username}) - self.assertEqual(0, len(raw_output)) - - def test_user_list(self): - raw_output = self.openstack('user list') - items = self.parse_listing(raw_output) - self.assert_table_structure(items, common.BASIC_LIST_HEADERS) - - def test_user_set(self): - username = self._create_dummy_user() - raw_output = self.openstack('user show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': username}) - user = self.parse_show_as_object(raw_output) - new_username = data_utils.rand_name('NewTestUser') - new_email = data_utils.rand_name() + '@example.com' - raw_output = self.openstack('user set ' - '--email %(email)s ' - '--name %(new_name)s ' - '%(id)s' % {'email': new_email, - 'new_name': new_username, - 'id': user['id']}) - self.assertEqual(0, len(raw_output)) - raw_output = self.openstack('user show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': new_username}) - updated_user = self.parse_show_as_object(raw_output) - self.assertEqual(user['id'], updated_user['id']) - self.assertEqual(new_email, updated_user['email']) - - def test_user_set_default_project_id(self): - username = self._create_dummy_user() - project_name = self._create_dummy_project() - # get original user details - raw_output = self.openstack('user show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': username}) - user = self.parse_show_as_object(raw_output) - # update user - raw_output = self.openstack('user set ' - '--project %(project)s ' - '--project-domain %(project_domain)s ' - '%(id)s' % {'project': project_name, - 'project_domain': - self.domain_name, - 'id': user['id']}) - self.assertEqual(0, len(raw_output)) - # get updated user details - raw_output = self.openstack('user show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': username}) - updated_user = self.parse_show_as_object(raw_output) - # get project details - raw_output = self.openstack('project show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': project_name}) - project = self.parse_show_as_object(raw_output) - # check updated user details - self.assertEqual(user['id'], updated_user['id']) - self.assertEqual(project['id'], updated_user['default_project_id']) - - def test_user_show(self): - username = self._create_dummy_user() - raw_output = self.openstack('user show ' - '--domain %(domain)s ' - '%(name)s' % {'domain': self.domain_name, - 'name': username}) - items = self.parse_show(raw_output) - self.assert_show_fields(items, self.USER_FIELDS) |
