summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-09-12 00:54:47 +0000
committerGerrit Code Review <review@openstack.org>2015-09-12 00:54:47 +0000
commit0c813d068b0d69fd141697378d5854389d22e282 (patch)
tree48d4aaa3f585bba8e06bc2d29e758f448a16fcd0
parentba69524e05578d1efae9aace3c4c7a8d25f77b2f (diff)
parent8c553fd4394a7f889627aca4f304e10168d3fd2c (diff)
downloadtrove-0c813d068b0d69fd141697378d5854389d22e282.tar.gz
Merge "Add user and database actions int-tests"
-rw-r--r--trove/tests/int_tests.py32
-rw-r--r--trove/tests/scenario/groups/database_actions_group.py63
-rw-r--r--trove/tests/scenario/groups/user_actions_group.py94
-rw-r--r--trove/tests/scenario/runners/database_actions_runners.py184
-rw-r--r--trove/tests/scenario/runners/user_actions_runners.py307
5 files changed, 670 insertions, 10 deletions
diff --git a/trove/tests/int_tests.py b/trove/tests/int_tests.py
index ff203bba..9ca0d967 100644
--- a/trove/tests/int_tests.py
+++ b/trove/tests/int_tests.py
@@ -36,10 +36,12 @@ from trove.tests.api import users
from trove.tests.api import versions
from trove.tests.scenario.groups import backup_group
from trove.tests.scenario.groups import cluster_actions_group
+from trove.tests.scenario.groups import database_actions_group
from trove.tests.scenario.groups import instance_actions_group
from trove.tests.scenario.groups import instance_delete_group
from trove.tests.scenario.groups import negative_cluster_actions_group
from trove.tests.scenario.groups import replication_group
+from trove.tests.scenario.groups import user_actions_group
GROUP_SERVICES_INITIALIZE = "services.initialize"
@@ -127,6 +129,12 @@ initial_groups = [
backup_groups = list(initial_groups)
backup_groups.extend([backup_group.GROUP])
+user_actions_groups = list(initial_groups)
+user_actions_groups.extend([user_actions_group.GROUP])
+
+database_actions_groups = list(initial_groups)
+database_actions_groups.extend([database_actions_group.GROUP])
+
cluster_actions_groups = list(initial_groups)
cluster_actions_groups.extend([cluster_actions_group.GROUP,
negative_cluster_actions_group.GROUP])
@@ -140,22 +148,26 @@ replication_groups.extend([replication_group.GROUP])
# Module based groups
register(["backup"], backup_groups)
register(["cluster"], cluster_actions_groups)
+register(["database"], database_actions_group)
register(["instance_actions"], instance_actions_groups)
+register(["user"], user_actions_groups)
register(["replication"], replication_groups)
# Datastore based groups - these should contain all functionality
# currently supported by the datastore
-register(["cassandra_group"], backup_groups, instance_actions_groups)
-register(["couchbase_group"], instance_actions_groups)
-register(["postgresql_group"], backup_groups, instance_actions_groups)
-register(["mongodb_group"], backup_groups, cluster_actions_groups,
- instance_actions_groups)
-register(["mysql_group"], backup_groups, instance_actions_groups,
+register(["cassandra_supported"], backup_groups, instance_actions_groups)
+register(["couchbase_supported"], instance_actions_groups)
+register(["postgresql_supported"], backup_groups, database_actions_groups,
+ instance_actions_groups, user_actions_groups)
+register(["mongodb_supported"], backup_groups, cluster_actions_groups,
+ database_actions_groups, instance_actions_groups, user_actions_groups)
+register(["mysql_supported"], backup_groups, database_actions_groups,
+ instance_actions_groups, replication_groups, user_actions_groups)
+register(["redis_supported"], backup_groups, instance_actions_groups,
replication_groups)
-register(["redis_group"], backup_groups, instance_actions_groups,
- replication_groups)
-register(["vertica_group"], cluster_actions_groups, instance_actions_groups)
-register(["pxc_group"], instance_actions_groups, cluster_actions_groups)
+register(["vertica_supported"], cluster_actions_groups,
+ instance_actions_groups)
+register(["pxc_supported"], instance_actions_groups, cluster_actions_groups)
# Redis int-tests
redis_group = [
diff --git a/trove/tests/scenario/groups/database_actions_group.py b/trove/tests/scenario/groups/database_actions_group.py
new file mode 100644
index 00000000..232ca357
--- /dev/null
+++ b/trove/tests/scenario/groups/database_actions_group.py
@@ -0,0 +1,63 @@
+# Copyright 2015 Tesora Inc.
+# All Rights Reserved.
+#
+# 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 proboscis import test
+
+from trove.tests.api.instances import GROUP_START_SIMPLE
+from trove.tests.api.instances import WaitForGuestInstallationToFinish
+from trove.tests.scenario.groups.test_group import TestGroup
+from trove.tests.scenario.groups import user_actions_group
+
+GROUP = "dbaas.api.database_actions_tests"
+
+
+@test(depends_on_groups=[GROUP_START_SIMPLE], groups=[GROUP],
+ runs_after=[WaitForGuestInstallationToFinish],
+ runs_after_groups=[user_actions_group.GROUP])
+class DatabaseActionsGroup(TestGroup):
+
+ def __init__(self):
+ super(DatabaseActionsGroup, self).__init__(
+ 'database_actions_runners', 'DatabaseActionsRunner')
+
+ @test
+ def create_databases(self):
+ self.test_runner.run_databases_create()
+
+ @test(depends_on=[create_databases])
+ def list_databases(self):
+ self.test_runner.run_databases_list()
+
+ @test(depends_on=[create_databases],
+ runs_after=[list_databases])
+ def negative_create_database(self):
+ self.test_runner.run_negative_database_create()
+
+ @test(depends_on=[create_databases],
+ runs_after=[negative_create_database])
+ def delete_database(self):
+ self.test_runner.run_database_delete()
+
+ @test
+ def nonexisting_database_delete(self):
+ self.test_runner.run_nonexisting_database_delete()
+
+ @test
+ def system_database_create(self):
+ self.test_runner.run_system_database_create()
+
+ @test
+ def system_database_delete(self):
+ self.test_runner.run_system_database_delete()
diff --git a/trove/tests/scenario/groups/user_actions_group.py b/trove/tests/scenario/groups/user_actions_group.py
new file mode 100644
index 00000000..92d3846e
--- /dev/null
+++ b/trove/tests/scenario/groups/user_actions_group.py
@@ -0,0 +1,94 @@
+# Copyright 2015 Tesora Inc.
+# All Rights Reserved.
+#
+# 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 proboscis import test
+
+from trove.tests.api.instances import GROUP_START_SIMPLE
+from trove.tests.api.instances import WaitForGuestInstallationToFinish
+from trove.tests.scenario.groups import instance_actions_group
+from trove.tests.scenario.groups.test_group import TestGroup
+
+GROUP = "dbaas.api.user_actions_tests"
+
+
+@test(depends_on_groups=[GROUP_START_SIMPLE], groups=[GROUP],
+ runs_after=[WaitForGuestInstallationToFinish],
+ runs_after_groups=[instance_actions_group.GROUP])
+class UserActionsGroup(TestGroup):
+
+ def __init__(self):
+ super(UserActionsGroup, self).__init__(
+ 'user_actions_runners', 'UserActionsRunner')
+
+ @test
+ def create_users(self):
+ self.test_runner.run_users_create()
+
+ @test(depends_on=[create_users])
+ def show_user(self):
+ self.test_runner.run_user_show()
+
+ @test(depends_on=[create_users],
+ runs_after=[show_user])
+ def list_users(self):
+ self.test_runner.run_users_list()
+
+ @test(depends_on=[create_users],
+ runs_after=[list_users])
+ def negative_create_user(self):
+ self.test_runner.run_negative_user_create()
+
+ @test(depends_on=[create_users],
+ runs_after=[list_users])
+ def negative_user_attribute_update(self):
+ self.test_runner.run_negative_user_attribute_update()
+
+ @test(depends_on=[create_users],
+ runs_after=[negative_user_attribute_update])
+ def user_attribute_update(self):
+ self.test_runner.run_user_attribute_update()
+
+ @test(depends_on=[create_users],
+ runs_after=[user_attribute_update])
+ def delete_user(self):
+ self.test_runner.run_user_delete()
+
+ @test
+ def nonexisting_user_show(self):
+ self.test_runner.run_nonexisting_user_show()
+
+ @test
+ def nonexisting_user_attribute_update(self):
+ self.test_runner.run_nonexisting_user_update()
+
+ @test
+ def nonexisting_user_delete(self):
+ self.test_runner.run_nonexisting_user_delete()
+
+ @test
+ def system_user_create(self):
+ self.test_runner.run_system_user_create()
+
+ @test
+ def system_user_show(self):
+ self.test_runner.run_system_user_show()
+
+ @test
+ def system_user_attribute_update(self):
+ self.test_runner.run_system_user_attribute_update()
+
+ @test
+ def system_user_delete(self):
+ self.test_runner.run_system_user_delete()
diff --git a/trove/tests/scenario/runners/database_actions_runners.py b/trove/tests/scenario/runners/database_actions_runners.py
new file mode 100644
index 00000000..c2da8f62
--- /dev/null
+++ b/trove/tests/scenario/runners/database_actions_runners.py
@@ -0,0 +1,184 @@
+# Copyright 2015 Tesora Inc.
+# All Rights Reserved.
+#
+# 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 proboscis import asserts
+
+from trove.tests.scenario.runners.test_runners import TestRunner
+from troveclient.compat import exceptions
+
+
+class DatabaseActionsRunner(TestRunner):
+
+ # TODO(pmalik): I believe the 202 (Accepted) should be replaced by
+ # 200 (OK) as the actions are generally very fast and their results
+ # available immediately upon execution of the request. This would
+ # likely require replacing GA casts with calls which I believe are
+ # more appropriate anyways.
+
+ def run_databases_create(self, expected_http_code=202):
+ databases = [{"name": 'database1'},
+ {"name": 'database2'},
+ {"name": 'database3'}]
+ self.db_defs = self.assert_databases_create(
+ self.instance_info.id, databases, expected_http_code)
+
+ def assert_databases_create(self, instance_id, serial_databases_def,
+ expected_http_code):
+ self.rd_client.databases.create(instance_id, serial_databases_def)
+ self.assert_client_code(expected_http_code)
+ return serial_databases_def
+
+ def run_databases_list(self, expected_http_code=200):
+ self.assert_databases_list(
+ self.instance_info.id, self.db_defs, expected_http_code)
+
+ def assert_databases_list(self, instance_id, expected_database_defs,
+ expected_http_code, limit=2):
+ full_list = self.rd_client.databases.list(instance_id)
+ self.assert_client_code(expected_http_code)
+ listed_databases = {database.name: database for database in full_list}
+ asserts.assert_is_none(full_list.next,
+ "Unexpected pagination in the list.")
+
+ for database_def in expected_database_defs:
+ database_name = database_def['name']
+ asserts.assert_true(
+ database_name in listed_databases,
+ "Database not included in the 'database-list' output: %s" %
+ database_name)
+
+ # Check that the system (ignored) databases are not included in the
+ # output.
+ system_databases = self.get_system_databases()
+ asserts.assert_false(
+ any(name in listed_databases for name in system_databases),
+ "System databases should not be included in the 'database-list' "
+ "output.")
+
+ # Test list pagination.
+ list_page = self.rd_client.databases.list(instance_id, limit=limit)
+ self.assert_client_code(expected_http_code)
+
+ asserts.assert_true(len(list_page) <= limit)
+ asserts.assert_is_not_none(list_page.next, "List page is missing.")
+ marker = list_page.next
+
+ self.assert_pagination_match(list_page, full_list, 0, limit)
+ self.assert_pagination_match(
+ list_page[-1:], full_list, limit - 1, limit)
+
+ list_page = self.rd_client.databases.list(instance_id, marker=marker)
+ self.assert_client_code(expected_http_code)
+ self.assert_pagination_match(
+ list_page, full_list, limit, len(full_list))
+
+ def run_negative_database_create(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # Test with no attribites.
+ self.assert_databases_create_failure(
+ self.instance_info.id, {}, expected_exception, expected_http_code)
+
+ # Test with empty database name attribute.
+ self.assert_databases_create_failure(
+ self.instance_info.id, {'name': ''},
+ expected_exception, expected_http_code)
+
+ # Test creating an existing database.
+ self.assert_databases_create_failure(
+ self.instance_info.id, self.db_defs[0],
+ expected_exception, expected_http_code)
+
+ def assert_databases_create_failure(
+ self, instance_id, serial_databases_def,
+ expected_exception, expected_http_code):
+ self.assert_raises(
+ expected_exception, expected_http_code,
+ self.rd_client.databases.create, instance_id, serial_databases_def)
+
+ def run_system_database_create(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_databases = self.get_system_databases()
+ if system_databases:
+ for name in system_databases:
+ database_def = {'name': name, 'password': 'password1',
+ 'databases': []}
+ self.assert_databases_create_failure(
+ self.instance_info.id, database_def,
+ expected_exception, expected_http_code)
+
+ def run_database_delete(self, expected_http_code=202):
+ for database_def in self.db_defs:
+ self.assert_database_delete(
+ self.instance_info.id, database_def['name'],
+ expected_http_code)
+
+ def assert_database_delete(
+ self,
+ instance_id,
+ database_name,
+ expected_http_code):
+ self.rd_client.databases.delete(instance_id, database_name)
+ self.assert_client_code(expected_http_code)
+
+ for database in self.rd_client.databases.list(instance_id):
+ if database.name == database_name:
+ asserts.fail(
+ "Database still listed after delete: %s" %
+ database_name)
+
+ def run_nonexisting_database_delete(self, expected_http_code=202):
+ # Deleting a non-existing database is expected to succeed as if the
+ # database was deleted.
+ self.assert_database_delete(
+ self.instance_info.id, 'justashadow', expected_http_code)
+
+ def run_system_database_delete(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_databases = self.get_system_databases()
+ if system_databases:
+ for name in system_databases:
+ self.assert_database_delete_failure(
+ self.instance_info.id, name,
+ expected_exception, expected_http_code)
+
+ def assert_database_delete_failure(
+ self, instance_id, database_name,
+ expected_exception, expected_http_code):
+ self.assert_raises(expected_exception, expected_http_code,
+ self.rd_client.databases.delete,
+ instance_id, database_name)
+
+ def get_system_databases(self):
+ return self.get_datastore_config_property('ignore_dbs')
+
+
+class MysqlDatabaseActionsRunner(DatabaseActionsRunner):
+
+ def get_system_databases(self):
+ # It seems the client does not like this name.
+ # Does this particular name actually still have to be ignored after
+ # all the datadir changes?
+ return [name for name
+ in self.get_datastore_config_property('ignore_dbs')
+ if name != '#mysql50#lost+found']
diff --git a/trove/tests/scenario/runners/user_actions_runners.py b/trove/tests/scenario/runners/user_actions_runners.py
new file mode 100644
index 00000000..88e7d0fc
--- /dev/null
+++ b/trove/tests/scenario/runners/user_actions_runners.py
@@ -0,0 +1,307 @@
+# Copyright 2015 Tesora Inc.
+# All Rights Reserved.
+#
+# 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 proboscis import asserts
+
+from trove.tests.scenario.runners.test_runners import TestRunner
+from troveclient.compat import exceptions
+
+
+class UserActionsRunner(TestRunner):
+
+ # TODO(pmalik): I believe the 202 (Accepted) should be replaced by
+ # 200 (OK) as the actions are generally very fast and their results
+ # available immediately upon execution of the request. This would
+ # likely require replacing GA casts with calls which I believe are
+ # more appropriate anyways.
+
+ def run_users_create(self, expected_http_code=202):
+ users = [{'name': 'nodbguy', 'password': 'password1',
+ 'databases': []},
+ {'name': 'singledbguy', 'password': 'password1',
+ 'databases': [{'name': 'db1'}]},
+ {'name': 'multidbguy', 'password': 'password1',
+ 'databases': [{'name': 'db1', 'name': 'db2'}]}]
+ self.user_defs = self.assert_users_create(
+ self.instance_info.id, users, expected_http_code)
+
+ def assert_users_create(self, instance_id, serial_users_def,
+ expected_http_code):
+ self.rd_client.users.create(instance_id, serial_users_def)
+ self.assert_client_code(expected_http_code)
+ return serial_users_def
+
+ def run_user_show(self, expected_http_code=200):
+ for user_def in self.user_defs:
+ self.assert_user_show(
+ self.instance_info.id, user_def, expected_http_code)
+
+ def assert_user_show(self, instance_id, expected_user_def,
+ expected_http_code):
+ user_name = expected_user_def['name']
+ queried_user = self.rd_client.users.get(instance_id, user_name, '%')
+ self.assert_client_code(expected_http_code)
+ self._assert_user_matches(queried_user, expected_user_def)
+
+ def _assert_user_matches(self, user, expected_user_def):
+ user_name = expected_user_def['name']
+ asserts.assert_equal(user.name, expected_user_def['name'],
+ "Mismatch of names for user: %s" % user_name)
+ asserts.assert_equal(user.databases, expected_user_def['databases'],
+ "Mismatch of databases for user: %s" % user_name)
+
+ def run_users_list(self, expected_http_code=200):
+ self.assert_users_list(
+ self.instance_info.id, self.user_defs, expected_http_code)
+
+ def assert_users_list(self, instance_id, expected_user_defs,
+ expected_http_code, limit=2):
+ full_list = self.rd_client.users.list(instance_id)
+ self.assert_client_code(expected_http_code)
+ listed_users = {user.name: user for user in full_list}
+ asserts.assert_is_none(full_list.next,
+ "Unexpected pagination in the list.")
+
+ for user_def in expected_user_defs:
+ user_name = user_def['name']
+ asserts.assert_true(
+ user_name in listed_users,
+ "User not included in the 'user-list' output: %s" %
+ user_name)
+ self._assert_user_matches(listed_users[user_name], user_def)
+
+ # Check that the system (ignored) users are not included in the output.
+ system_users = self.get_system_users()
+ asserts.assert_false(
+ any(name in listed_users for name in system_users),
+ "System users should not be included in the 'user-list' output.")
+
+ # Test list pagination.
+ list_page = self.rd_client.users.list(instance_id, limit=limit)
+ self.assert_client_code(expected_http_code)
+
+ asserts.assert_true(len(list_page) <= limit)
+ asserts.assert_is_not_none(list_page.next, "List page is missing.")
+ marker = list_page.next
+
+ self.assert_pagination_match(list_page, full_list, 0, limit)
+ self.assert_pagination_match(
+ list_page[-1:], full_list, limit - 1, limit)
+
+ list_page = self.rd_client.users.list(instance_id, marker=marker)
+ self.assert_client_code(expected_http_code)
+ self.assert_pagination_match(
+ list_page, full_list, limit, len(full_list))
+
+ def run_negative_user_create(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # Test with no attribites.
+ self.assert_users_create_failure(
+ self.instance_info.id, {}, expected_exception, expected_http_code)
+
+ # Test with missing user name attribute.
+ self.assert_users_create_failure(
+ self.instance_info.id,
+ {'password': 'password1', 'databases': []},
+ expected_exception, expected_http_code)
+
+ # Test with empty user name attribute.
+ self.assert_users_create_failure(
+ self.instance_info.id,
+ {'name': '', 'password': 'password1', 'databases': []},
+ expected_exception, expected_http_code)
+
+ # Test with missing password attribute.
+ self.assert_users_create_failure(
+ self.instance_info.id,
+ {'name': 'nopassguy', 'databases': []},
+ expected_exception, expected_http_code)
+
+ # Test with missing databases attribute.
+ self.assert_users_create_failure(
+ self.instance_info.id,
+ {'name': 'nodbguy', 'password': 'password1'},
+ expected_exception, expected_http_code)
+
+ # Test creating an existing user.
+ self.assert_users_create_failure(
+ self.instance_info.id, self.user_defs[0],
+ expected_exception, expected_http_code)
+
+ def run_system_user_create(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_users = self.get_system_users()
+ if system_users:
+ for name in system_users:
+ user_def = {'name': name, 'password': 'password1',
+ 'databases': []}
+ self.assert_users_create_failure(
+ self.instance_info.id, user_def,
+ expected_exception, expected_http_code)
+
+ def assert_users_create_failure(
+ self, instance_id, serial_users_def,
+ expected_exception, expected_http_code):
+ self.assert_raises(
+ expected_exception, expected_http_code,
+ self.rd_client.users.create, instance_id, serial_users_def)
+
+ def run_negative_user_attribute_update(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # Test some basic invalid attributes on an existing user.
+
+ # Test with no attribites.
+ # Note: this is caught on the client-side.
+ self.assert_user_attribute_update_failure(
+ self.instance_info.id, 'nodbguy', {}, Exception, None)
+
+ # Test with empty user name.
+ self.assert_user_attribute_update_failure(
+ self.instance_info.id, 'nodbguy', {'name': ''},
+ expected_exception, expected_http_code)
+
+ # Test updating an existing user with a conflicting name.
+ self.assert_user_attribute_update_failure(
+ self.instance_info.id, self.user_defs[0]['name'],
+ {'name': self.user_defs[1]['name']},
+ expected_exception, expected_http_code)
+
+ def assert_user_attribute_update_failure(
+ self, instance_id, user_name, update_attribites,
+ expected_exception, expected_http_code):
+ self.assert_raises(
+ expected_exception, expected_http_code,
+ self.rd_client.users.update_attributes, instance_id,
+ user_name, update_attribites)
+
+ def run_system_user_attribute_update(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_users = self.get_system_users()
+ if system_users:
+ for name in system_users:
+ update_attribites = {'name': name, 'password': 'password2'}
+ self.assert_user_attribute_update_failure(
+ self.instance_info.id, name, update_attribites,
+ expected_exception, expected_http_code)
+
+ def run_user_attribute_update(self, expected_http_code=202):
+ update_attribites = {'name': 'dblessguy', 'password': 'password2'}
+ self.assert_user_attribute_update(
+ self.instance_info.id, 'nodbguy', update_attribites,
+ expected_http_code)
+
+ def assert_user_attribute_update(self, instance_id, user_name,
+ update_attribites, expected_http_code):
+ self.rd_client.users.update_attributes(
+ instance_id, user_name, update_attribites)
+ self.assert_client_code(expected_http_code)
+
+ # Update the stored definitions with the new value.
+ expected_def = None
+ for user_def in self.user_defs:
+ if user_def['name'] == user_name:
+ user_def.update(update_attribites)
+ expected_def = user_def
+
+ # Verify using 'user-show' and 'user-list'.
+ self.assert_user_show(instance_id, expected_def, 200)
+ self.assert_users_list(instance_id, self.user_defs, 200)
+
+ def run_user_delete(self, expected_http_code=202):
+ for user_def in self.user_defs:
+ self.assert_user_delete(
+ self.instance_info.id, user_def['name'], expected_http_code)
+
+ def assert_user_delete(self, instance_id, user_name, expected_http_code):
+ self.rd_client.users.delete(instance_id, user_name)
+ self.assert_client_code(expected_http_code)
+
+ self.assert_raises(exceptions.NotFound, 404,
+ self.rd_client.users.get,
+ instance_id, user_name, '%')
+
+ for user in self.rd_client.users.list(instance_id):
+ if user.name == user_name:
+ asserts.fail("User still listed after delete: %s" % user_name)
+
+ def run_nonexisting_user_show(
+ self, expected_exception=exceptions.NotFound,
+ expected_http_code=404):
+ self.assert_user_show_failure(self.instance_info.id, 'nonexistingusr',
+ expected_exception, expected_http_code)
+
+ def assert_user_show_failure(self, instance_id, user_name,
+ expected_exception, expected_http_code):
+ self.assert_raises(
+ expected_exception, expected_http_code,
+ self.rd_client.users.get, instance_id, user_name, '%')
+
+ def run_system_user_show(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_users = self.get_system_users()
+ if system_users:
+ for name in system_users:
+ self.assert_user_show_failure(
+ self.instance_info.id, name,
+ expected_exception, expected_http_code)
+
+ def run_nonexisting_user_update(self, expected_http_code=404):
+ # Test valid update on a non-existing user.
+ self.assert_user_attribute_update_failure(
+ self.instance_info.id, 'nonexistingusr', {'name': 'justashadow'},
+ exceptions.NotFound, expected_http_code)
+
+ def run_nonexisting_user_delete(
+ self, expected_exception=exceptions.NotFound,
+ expected_http_code=404):
+ self.assert_user_delete_failure(self.instance_info.id, 'justashadow',
+ expected_exception, expected_http_code)
+
+ def assert_user_delete_failure(
+ self, instance_id, user_name,
+ expected_exception, expected_http_code):
+ self.assert_raises(expected_exception, expected_http_code,
+ self.rd_client.users.delete,
+ instance_id, user_name)
+
+ def run_system_user_delete(
+ self, expected_exception=exceptions.BadRequest,
+ expected_http_code=400):
+ # TODO(pmalik): Actions on system users and databases should probably
+ # return Forbidden 403 instead. The current error messages are
+ # confusing (talking about a malformed request).
+ system_users = self.get_system_users()
+ if system_users:
+ for name in system_users:
+ self.assert_user_delete_failure(
+ self.instance_info.id, name,
+ expected_exception, expected_http_code)
+
+ def get_system_users(self):
+ return self.get_datastore_config_property('ignore_users')