Update the root scenario tests

Incorporate the changes made as a part of the cluster-root
tests introduced in review 266005:

    - add test scenario for: bug 1549600
    - simplify turning off unsupported root-disable tests
      by introducing a single assertion hook that runs before all
      related tests
    - ping the datastore as root to verify it can connect
    - ping after root-disable to verify it cannot connect
    - add missing ping implementations to Cassandra and Redis helpers
    - enable root with password tests on MySQL and related
    - use the same helper method to get root credentials as
      the cluster-root tests
    - also assert the expected root-user-name if specified
    - cleanup auxiliary backup
    - add Postgres root credentials
    - Skip root-cluster test on Redis
    - minor cleanup
    - increased the low guestagent call timeout (helps tests
      run more stable).

Depends-On: I8a4321ac062b1ec565945b49dbb7c619b6da867f

Change-Id: I3fb0a8bb37fd124c22573552ff61852ead23e9a0
Related-Bug: 1529965
Related-Bug: 1549969
Related-Bug: 1549600
This commit is contained in:
Petr Malik 2016-02-23 13:58:47 -05:00
parent d969b08e52
commit 6ace3dda60
9 changed files with 192 additions and 83 deletions

View File

@ -123,6 +123,7 @@ function configure_trove {
setup_trove_logging $TROVE_TASKMANAGER_CONF
# Increase default timeouts (required by the tests).
iniset $TROVE_TASKMANAGER_CONF DEFAULT agent_call_low_timeout 15
iniset $TROVE_TASKMANAGER_CONF DEFAULT agent_call_high_timeout 300
iniset $TROVE_TASKMANAGER_CONF DEFAULT usage_timeout 1200
fi

View File

@ -30,6 +30,8 @@ class RootActionsGroup(TestGroup):
'root_actions_runners', 'RootActionsRunner')
self.backup_runner = self.get_runner(
'backup_runners', 'BackupRunner')
self.backup_runner2 = self.get_runner(
'backup_runners', 'BackupRunner')
@test
def check_root_never_enabled(self):
@ -39,6 +41,7 @@ class RootActionsGroup(TestGroup):
@test(depends_on=[check_root_never_enabled])
def disable_root_before_enabled(self):
"""Ensure disable fails if root was never enabled."""
self.test_runner.check_root_disable_supported()
self.test_runner.run_disable_root_before_enabled()
@test(depends_on=[check_root_never_enabled],
@ -77,21 +80,36 @@ class RootActionsGroup(TestGroup):
@test(depends_on=[enable_root_with_password])
def check_root_still_enabled(self):
"""Check the root is still enabled."""
self.test_runner.run_check_root_still_enabled()
self.test_runner.run_check_root_enabled()
@test(depends_on=[check_root_enabled],
runs_after=[check_root_still_enabled])
def disable_root(self):
"""Disable root."""
self.test_runner.check_root_disable_supported()
self.test_runner.run_disable_root()
@test(depends_on=[disable_root])
def check_root_still_enabled_after_disable(self):
"""Check the root is still marked as enabled after disable."""
self.test_runner.check_root_disable_supported()
self.test_runner.run_check_root_still_enabled_after_disable()
@test(depends_on=[check_root_still_enabled_after_disable])
def backup_root_disabled_instance(self):
"""Backup the root-disabled instance."""
self.test_runner.check_root_disable_supported()
self.backup_runner2.run_backup_create()
self.backup_runner2.run_backup_create_completed()
@test(depends_on=[backup_root_disabled_instance])
def restore_root_disabled_instance(self):
"""Restore the root-disabled instance."""
self.test_runner.check_root_disable_supported()
self.backup_runner2.run_restore_from_backup()
@test(depends_on=[restore_root_enabled_instance],
runs_after=[check_root_still_enabled_after_disable])
runs_after=[restore_root_disabled_instance])
def wait_for_restored_instance(self):
"""Wait until restoring a root-enabled instance completes."""
self.backup_runner.run_restore_from_backup_completed()
@ -100,10 +118,47 @@ class RootActionsGroup(TestGroup):
def check_root_enabled_after_restore(self):
"""Check the root is also enabled on the restored instance."""
instance_id = self.backup_runner.restore_instance_id
self.test_runner.run_check_root_enabled_after_restore(instance_id)
root_creds = self.test_runner.restored_root_creds
self.test_runner.run_check_root_enabled_after_restore(
instance_id, root_creds)
@test(depends_on=[restore_root_disabled_instance],
runs_after=[check_root_enabled_after_restore])
def wait_for_restored_instance2(self):
"""Wait until restoring a root-disabled instance completes."""
self.test_runner.check_root_disable_supported()
self.backup_runner2.run_restore_from_backup_completed()
@test(depends_on=[wait_for_restored_instance2])
def check_root_enabled_after_restore2(self):
"""Check the root is also enabled on the restored instance."""
instance_id = self.backup_runner2.restore_instance_id
root_creds = self.test_runner.restored_root_creds2
self.test_runner.run_check_root_enabled_after_restore2(
instance_id, root_creds)
@test(depends_on=[wait_for_restored_instance],
runs_after=[check_root_enabled_after_restore])
def delete_restored_instance(self):
"""Delete root restored instances."""
"""Delete the restored root-enabled instance."""
self.backup_runner.run_delete_restored_instance()
@test(depends_on=[backup_root_enabled_instance],
runs_after=[delete_restored_instance])
def delete_instance_backup(self):
"""Delete the root-enabled instance backup."""
self.backup_runner.run_delete_backup()
@test(depends_on=[wait_for_restored_instance2],
runs_after=[check_root_enabled_after_restore2])
def delete_restored_instance2(self):
"""Delete the restored root-disabled instance."""
self.test_runner.check_root_disable_supported()
self.backup_runner2.run_delete_restored_instance()
@test(depends_on=[backup_root_disabled_instance],
runs_after=[delete_restored_instance2])
def delete_instance_backup2(self):
"""Delete the root-disabled instance backup."""
self.test_runner.check_root_disable_supported()
self.backup_runner2.run_delete_backup()

View File

@ -65,8 +65,10 @@ class CassandraHelper(TestHelper):
def create_client(self, host, *args, **kwargs):
user = self.get_helper_credentials()
return CassandraClient(
[host], user['name'], user['password'], user['database'])
username = kwargs.get('username', user['name'])
password = kwargs.get('password', user['password'])
database = kwargs.get('database', user['database'])
return CassandraClient([host], username, password, database)
def add_actual_data(self, data_label, data_start, data_size, host,
*args, **kwargs):
@ -131,6 +133,13 @@ class CassandraHelper(TestHelper):
def get_helper_credentials(self):
return {'name': 'lite', 'password': 'litepass', 'database': 'firstdb'}
def ping(self, host, *args, **kwargs):
try:
self.get_client(host, *args, **kwargs)
return True
except Exception:
return False
def get_valid_database_definitions(self):
return [{"name": 'db1'}, {"name": 'db2'}, {"name": 'db3'}]

View File

@ -31,6 +31,9 @@ class PostgresqlHelper(SqlHelper):
# for the user to be able to login.
return {'name': 'lite', 'password': 'litepass', 'database': 'lite'}
def get_helper_credentials_root(self):
return {'name': 'postgres', 'password': 'rootpass'}
def get_valid_database_definitions(self):
return [{'name': 'db1'}, {'name': 'db2'}, {'name': 'db3'}]

View File

@ -48,7 +48,8 @@ class RedisHelper(TestHelper):
def create_client(self, host, *args, **kwargs):
user = self.get_helper_credentials()
client = redis.StrictRedis(password=user['password'], host=host)
password = kwargs.get('password', user['password'])
client = redis.StrictRedis(password=password, host=host)
return client
# Add data overrides
@ -175,3 +176,10 @@ class RedisHelper(TestHelper):
def get_invalid_groups(self):
return [{'hz': 600}, {'databases': -1}, {'databases': 'string_value'}]
def ping(self, host, *args, **kwargs):
try:
client = self.get_client(host, *args, **kwargs)
return client.ping() == 'PONG'
except Exception:
return False

View File

@ -43,14 +43,12 @@ class SqlHelper(TestHelper):
return self.credentials['database']
def create_client(self, host, *args, **kwargs):
username = kwargs.get("username")
password = kwargs.get("password")
if username and password:
creds = {"name": username, "password": password}
return sqlalchemy.create_engine(
self._build_connection_string(host, creds))
username = kwargs.get('username', self.credentials['name'])
password = kwargs.get('password', self.credentials['password'])
database = kwargs.get('database', self.credentials['database'])
creds = {"name": username, "password": password, "database": database}
return sqlalchemy.create_engine(
self._build_connection_string(host, self.credentials))
self._build_connection_string(host, creds))
def _build_connection_string(self, host, creds):
if self.port:
@ -136,8 +134,12 @@ class SqlHelper(TestHelper):
return client.execute(data_table.select()).fetchall()
def ping(self, host, *args, **kwargs):
root_client = self.get_client(host, *args, **kwargs)
root_client.execute("SELECT 1;")
try:
root_client = self.get_client(host, *args, **kwargs)
root_client.execute("SELECT 1;")
return True
except Exception:
return False
def get_configuration_value(self, property_name, host, *args, **kwargs):
client = self.get_client(host, *args, **kwargs)

View File

@ -158,6 +158,17 @@ class TestHelper(object):
"""
return {'name': None, 'password': None, 'database': None}
def ping(self, host, *args, **kwargs):
"""Try to connect to a given host and perform a simple read-only
action.
Return True on success or False otherwise.
"""
pass
##############
# Root related
##############
def get_helper_credentials_root(self):
"""Return the credentials that the client will be using to
access the database as root.
@ -433,14 +444,6 @@ class TestHelper(object):
"""
return False
##############
# Root related
##############
def get_valid_root_password(self):
"""Return a valid password that can be used by a 'root' user.
"""
return "RootTestPass"
##############
# Module related
##############

View File

@ -133,11 +133,13 @@ class ClusterActionsRunner(TestRunner):
root_enabled_test = self.auth_client.root.is_instance_root_enabled(
instance['id'])
self.assert_true(root_enabled_test.rootEnabled)
self.test_helper.ping(
ping_response = self.test_helper.ping(
cluster.ip[0],
username=self.current_root_creds[0],
password=self.current_root_creds[1]
)
self.assert_true(ping_response)
def run_add_initial_cluster_data(self, data_type=DataType.tiny):
self.assert_add_cluster_data(data_type, self.cluster_id)

View File

@ -23,6 +23,8 @@ class RootActionsRunner(TestRunner):
def __init__(self):
self.current_root_creds = None
self.restored_root_creds = None
self.restored_root_creds2 = None
super(RootActionsRunner, self).__init__()
def run_check_root_never_enabled(self, expected_http_code=200):
@ -53,20 +55,45 @@ class RootActionsRunner(TestRunner):
self.auth_client.root.delete, instance_id)
def run_enable_root_no_password(self, expected_http_code=200):
root_credentials = self.test_helper.get_helper_credentials_root()
self.current_root_creds = self.assert_root_create(
self.instance_info.id, None, expected_http_code)
self.instance_info.id, None, root_credentials['name'],
expected_http_code)
self.restored_root_creds = list(self.current_root_creds)
def assert_root_create(self, instance_id, root_password,
expected_http_code):
if root_password:
expected_root_name, expected_http_code):
if root_password is not None:
root_creds = self.auth_client.root.create_instance_root(
instance_id, root_password)
self.assert_equal(root_password, root_creds[1])
else:
root_creds = self.auth_client.root.create(instance_id)
if expected_root_name is not None:
self.assert_equal(expected_root_name, root_creds[0])
self.assert_instance_action(instance_id, None, expected_http_code)
self.assert_can_connect(instance_id, root_creds)
return root_creds
def assert_can_connect(self, instance_id, test_connect_creds):
self._assert_connect(instance_id, True, test_connect_creds)
def _assert_connect(
self, instance_id, expected_response, test_connect_creds):
host = self.get_instance_host(instance_id=instance_id)
self.report.log("Pinging instance %s with credentials: %s"
% (instance_id, test_connect_creds))
ping_response = self.test_helper.ping(
host,
username=test_connect_creds[0],
password=test_connect_creds[1]
)
self.assert_equal(expected_response, ping_response)
def run_check_root_enabled(self, expected_http_code=200):
self.assert_root_enabled(self.instance_info.id, expected_http_code)
@ -76,19 +103,29 @@ class RootActionsRunner(TestRunner):
"instance yet.")
def run_enable_root_with_password(self, expected_http_code=200):
password = self.test_helper.get_valid_root_password()
self.current_root_creds = self.assert_root_create(
self.instance_info.id, password, expected_http_code)
def run_check_root_still_enabled(self, expected_http_code=200):
self.assert_root_enabled(self.instance_info.id, expected_http_code)
root_credentials = self.test_helper.get_helper_credentials_root()
password = root_credentials['password']
if password is not None:
self.current_root_creds = self.assert_root_create(
self.instance_info.id,
password, root_credentials['name'],
expected_http_code)
else:
raise SkipTest("No valid root password defined in %s."
% self.test_helper.get_class_name())
def run_disable_root(self, expected_http_code=200):
self.restored_root_creds2 = list(self.current_root_creds)
self.assert_root_disable(self.instance_info.id, expected_http_code)
def assert_root_disable(self, instance_id, expected_http_code):
self.auth_client.root.delete(instance_id)
self.assert_instance_action(instance_id, None, expected_http_code)
self.assert_cannot_connect(self.instance_info.id,
self.current_root_creds)
def assert_cannot_connect(self, instance_id, test_connect_creds):
self._assert_connect(instance_id, False, test_connect_creds)
def run_check_root_still_enabled_after_disable(
self, expected_http_code=200):
@ -106,75 +143,64 @@ class RootActionsRunner(TestRunner):
self.auth_client.users.delete,
instance_id, root_user_name)
def run_check_root_enabled_after_restore(self, restored_instance_id,
expected_http_code=200):
def run_check_root_enabled_after_restore(
self, restored_instance_id, restored_creds,
expected_http_code=200):
self.assert_root_enabled_after_restore(
restored_instance_id, restored_creds, True, expected_http_code)
def run_check_root_enabled_after_restore2(
self, restored_instance_id, restored_creds,
expected_http_code=200):
self.assert_root_enabled_after_restore(
restored_instance_id, restored_creds, False, expected_http_code)
def assert_root_enabled_after_restore(
self, restored_instance_id, restored_creds,
expected_connect_response, expected_http_code):
if restored_instance_id:
self.assert_root_enabled(restored_instance_id, expected_http_code)
self._assert_connect(restored_instance_id,
expected_connect_response, restored_creds)
else:
raise SkipTest("No instance with enabled root restored.")
raise SkipTest("No restored instance.")
class MysqlRootActionsRunner(RootActionsRunner):
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
def check_root_disable_supported(self):
"""Throw SkipTest if root-disable is not supported."""
pass
class PerconaRootActionsRunner(RootActionsRunner):
def run_disable_root_before_enabled(self):
raise SkipTest("Operation is currently not supported.")
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
def run_disable_root(self):
def check_root_disable_supported(self):
raise SkipTest("Operation is currently not supported.")
class MariadbRootActionsRunner(RootActionsRunner):
def run_disable_root_before_enabled(self):
raise SkipTest("Operation is currently not supported.")
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
def run_disable_root(self):
raise SkipTest("Operation is currently not supported.")
class PostgresqlRootActionsRunner(RootActionsRunner):
def run_disable_root_before_enabled(self):
raise SkipTest("Operation is currently not supported.")
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
def run_disable_root(self):
raise SkipTest("Operation is currently not supported.")
class CouchbaseRootActionsRunner(RootActionsRunner):
def run_disable_root_before_enabled(self):
raise SkipTest("Operation is currently not supported.")
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
def run_disable_root(self):
def check_root_disable_supported(self):
raise SkipTest("Operation is currently not supported.")
class PxcRootActionsRunner(RootActionsRunner):
def run_disable_root_before_enabled(self):
def check_root_disable_supported(self):
raise SkipTest("Operation is currently not supported.")
def run_disable_root(self):
class PostgresqlRootActionsRunner(RootActionsRunner):
def check_root_disable_supported(self):
raise SkipTest("Operation is currently not supported.")
def check_root_still_enabled_after_disable(self):
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")
class CouchbaseRootActionsRunner(RootActionsRunner):
def check_root_disable_supported(self):
raise SkipTest("Operation is currently not supported.")
def run_enable_root_with_password(self):
raise SkipTest("Operation is currently not supported.")