diff --git a/trove/tests/int_tests.py b/trove/tests/int_tests.py index 5938dc33c1..80d92eca08 100644 --- a/trove/tests/int_tests.py +++ b/trove/tests/int_tests.py @@ -156,9 +156,6 @@ guest_log_groups.extend([guest_log_group.GROUP]) instance_actions_groups = list(instance_create_groups) instance_actions_groups.extend([instance_actions_group.GROUP]) -instance_module_groups = list(instance_create_groups) -instance_module_groups.extend([module_group.GROUP_INSTANCE_MODULE]) - module_groups = list(instance_create_groups) module_groups.extend([module_group.GROUP]) @@ -187,7 +184,6 @@ register(["database"], database_actions_groups) register(["guest_log"], guest_log_groups) register(["instance", "instance_actions"], instance_actions_groups) register(["instance_create"], instance_create_groups) -register(["instance_module"], instance_module_groups) register(["module"], module_groups) register(["module_create"], module_create_groups) register(["replication"], replication_groups) diff --git a/trove/tests/scenario/groups/backup_group.py b/trove/tests/scenario/groups/backup_group.py index 964686d44e..9185f730d9 100644 --- a/trove/tests/scenario/groups/backup_group.py +++ b/trove/tests/scenario/groups/backup_group.py @@ -17,6 +17,7 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.backup_restore_group" @@ -25,13 +26,19 @@ GROUP_BACKUP_LIST = "scenario.backup_list_group" GROUP_RESTORE = "scenario.restore_group" +class BackupRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'backup_runners' + _runner_cls = 'BackupRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class BackupGroup(TestGroup): """Test Backup and Restore functionality.""" def __init__(self): super(BackupGroup, self).__init__( - 'backup_runners', 'BackupRunner') + BackupRunnerFactory.instance()) @test(groups=[GROUP_BACKUP]) def backup_create_instance_invalid(self): diff --git a/trove/tests/scenario/groups/cluster_actions_group.py b/trove/tests/scenario/groups/cluster_actions_group.py index 893da232fd..3469b5a980 100644 --- a/trove/tests/scenario/groups/cluster_actions_group.py +++ b/trove/tests/scenario/groups/cluster_actions_group.py @@ -16,17 +16,24 @@ from proboscis import test from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.cluster_actions_group" +class ClusterActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'cluster_actions_runners' + _runner_cls = 'ClusterActionsRunner' + + @test(groups=[GROUP]) class ClusterActionsGroup(TestGroup): def __init__(self): super(ClusterActionsGroup, self).__init__( - 'cluster_actions_runners', 'ClusterActionsRunner') + ClusterActionsRunnerFactory.instance()) @test def cluster_create(self): diff --git a/trove/tests/scenario/groups/configuration_group.py b/trove/tests/scenario/groups/configuration_group.py index 4d7b274e70..bd58a0594a 100644 --- a/trove/tests/scenario/groups/configuration_group.py +++ b/trove/tests/scenario/groups/configuration_group.py @@ -17,17 +17,24 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.configuration_group" +class ConfigurationRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'configuration_runners' + _runner_cls = 'ConfigurationRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class ConfigurationGroup(TestGroup): def __init__(self): super(ConfigurationGroup, self).__init__( - 'configuration_runners', 'ConfigurationRunner') + ConfigurationRunnerFactory.instance()) @test def create_bad_group(self): diff --git a/trove/tests/scenario/groups/database_actions_group.py b/trove/tests/scenario/groups/database_actions_group.py index 7519507fc9..082c33b030 100644 --- a/trove/tests/scenario/groups/database_actions_group.py +++ b/trove/tests/scenario/groups/database_actions_group.py @@ -17,19 +17,26 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.database_actions_group" +class DatabaseActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'database_actions_runners' + _runner_cls = 'DatabaseActionsRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class DatabaseActionsGroup(TestGroup): def __init__(self): super(DatabaseActionsGroup, self).__init__( - 'database_actions_runners', 'DatabaseActionsRunner') - self.instance_create_runner = self.get_runner( - 'instance_create_runners', 'InstanceCreateRunner') + DatabaseActionsRunnerFactory.instance()) + self.instance_create_runner = ( + instance_create_group.InstanceCreateRunnerFactory.create()) @test def create_initialized_instance(self): diff --git a/trove/tests/scenario/groups/guest_log_group.py b/trove/tests/scenario/groups/guest_log_group.py index 9bc39e588e..24cd8058db 100644 --- a/trove/tests/scenario/groups/guest_log_group.py +++ b/trove/tests/scenario/groups/guest_log_group.py @@ -16,18 +16,25 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.guest_log_group" +class GuestLogRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'guest_log_runners' + _runner_cls = 'GuestLogRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class GuestLogGroup(TestGroup): """Test Guest Log functionality.""" def __init__(self): super(GuestLogGroup, self).__init__( - 'guest_log_runners', 'GuestLogRunner') + GuestLogRunnerFactory.instance()) @test def test_log_list(self): diff --git a/trove/tests/scenario/groups/instance_actions_group.py b/trove/tests/scenario/groups/instance_actions_group.py index 240c52305e..0f2e777f18 100644 --- a/trove/tests/scenario/groups/instance_actions_group.py +++ b/trove/tests/scenario/groups/instance_actions_group.py @@ -17,17 +17,24 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.instance_actions_group" +class InstanceActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'instance_actions_runners' + _runner_cls = 'InstanceActionsRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class InstanceActionsGroup(TestGroup): def __init__(self): super(InstanceActionsGroup, self).__init__( - 'instance_actions_runners', 'InstanceActionsRunner') + InstanceActionsRunnerFactory.instance()) @test def instance_restart(self): diff --git a/trove/tests/scenario/groups/instance_create_group.py b/trove/tests/scenario/groups/instance_create_group.py index de3bdb3a64..cecdea35a5 100644 --- a/trove/tests/scenario/groups/instance_create_group.py +++ b/trove/tests/scenario/groups/instance_create_group.py @@ -15,21 +15,28 @@ from proboscis import test -from trove.tests.api.instances import InstanceSetup from trove.tests import PRE_INSTANCES from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.instance_create_group" -@test(depends_on_classes=[InstanceSetup], runs_after_groups=[PRE_INSTANCES], - groups=[GROUP]) +class InstanceCreateRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'instance_create_runners' + _runner_cls = 'InstanceCreateRunner' + + +@test(groups=[GROUP], + depends_on_groups=["services.initialize"], + runs_after_groups=[PRE_INSTANCES]) class InstanceCreateGroup(TestGroup): def __init__(self): super(InstanceCreateGroup, self).__init__( - 'instance_create_runners', 'InstanceCreateRunner') + InstanceCreateRunnerFactory.instance()) @test def create_empty_instance(self): diff --git a/trove/tests/scenario/groups/instance_delete_group.py b/trove/tests/scenario/groups/instance_delete_group.py index 00e2c93381..de1492d5fe 100644 --- a/trove/tests/scenario/groups/instance_delete_group.py +++ b/trove/tests/scenario/groups/instance_delete_group.py @@ -25,11 +25,18 @@ from trove.tests.scenario.groups import replication_group from trove.tests.scenario.groups import root_actions_group from trove.tests.scenario.groups.test_group import TestGroup from trove.tests.scenario.groups import user_actions_group +from trove.tests.scenario.runners import test_runners GROUP = "scenario.instance_delete_group" +class InstanceDeleteRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'instance_delete_runners' + _runner_cls = 'InstanceDeleteRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP], runs_after_groups=[backup_group.GROUP_BACKUP, @@ -44,7 +51,7 @@ class InstanceDeleteGroup(TestGroup): def __init__(self): super(InstanceDeleteGroup, self).__init__( - 'instance_delete_runners', 'InstanceDeleteRunner') + InstanceDeleteRunnerFactory.instance()) @test def instance_delete(self): diff --git a/trove/tests/scenario/groups/module_group.py b/trove/tests/scenario/groups/module_group.py index 4dc5441d03..7c8cb021c3 100644 --- a/trove/tests/scenario/groups/module_group.py +++ b/trove/tests/scenario/groups/module_group.py @@ -18,21 +18,28 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.module_group" GROUP_MODULE_CREATE = "scenario.module_create_group" -GROUP_INSTANCE_MODULE = "scenario.instance_module_group" +GROUP_MODULE_INSTANCE = "scenario.module_instance_group" GROUP_MODULE_DELETE = "scenario.module_delete_group" +class ModuleRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'module_runners' + _runner_cls = 'ModuleRunner' + + @test(groups=[GROUP, GROUP_MODULE_CREATE]) class ModuleGroup(TestGroup): """Test Module functionality.""" def __init__(self): super(ModuleGroup, self).__init__( - 'module_runners', 'ModuleRunner') + ModuleRunnerFactory.instance()) @test(groups=[GROUP, GROUP_MODULE_CREATE]) def module_delete_existing(self): @@ -319,63 +326,63 @@ class ModuleGroup(TestGroup): @test(depends_on_groups=[instance_create_group.GROUP, GROUP_MODULE_CREATE], - groups=[GROUP, GROUP_INSTANCE_MODULE]) + groups=[GROUP, GROUP_MODULE_INSTANCE]) class ModuleInstanceGroup(TestGroup): """Test Instance Module functionality.""" def __init__(self): super(ModuleInstanceGroup, self).__init__( - 'module_runners', 'ModuleRunner') + ModuleRunnerFactory.instance()) - @test(groups=[GROUP, GROUP_INSTANCE_MODULE]) + @test(groups=[GROUP, GROUP_MODULE_INSTANCE]) def module_list_instance_empty(self): """Check that the instance has no modules associated.""" self.test_runner.run_module_list_instance_empty() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], runs_after=[module_list_instance_empty]) def module_instances_empty(self): """Check that the module hasn't been applied to any instances.""" self.test_runner.run_module_instances_empty() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], runs_after=[module_instances_empty]) def module_query_empty(self): """Check that the instance has no modules applied.""" self.test_runner.run_module_query_empty() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], runs_after=[module_query_empty]) def module_apply(self): """Check that module-apply works.""" self.test_runner.run_module_apply() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_apply]) def module_list_instance_after_apply(self): """Check that the instance has one module associated.""" self.test_runner.run_module_list_instance_after_apply() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_apply]) def module_query_after_apply(self): """Check that module-query works.""" self.test_runner.run_module_query_after_apply() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_apply], runs_after=[module_query_after_apply]) def create_inst_with_mods(self): """Check that creating an instance with modules works.""" self.test_runner.run_create_inst_with_mods() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_apply]) def module_delete_applied(self): """Ensure that deleting an applied module fails.""" self.test_runner.run_module_delete_applied() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_apply], runs_after=[module_list_instance_after_apply, module_query_after_apply]) @@ -383,54 +390,54 @@ class ModuleInstanceGroup(TestGroup): """Check that module-remove works.""" self.test_runner.run_module_remove() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[module_remove]) def module_query_empty_after(self): """Check that the instance has no modules applied after remove.""" self.test_runner.run_module_query_empty() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[create_inst_with_mods], runs_after=[module_query_empty_after]) def wait_for_inst_with_mods(self): """Wait for create instance with modules to finish.""" self.test_runner.run_wait_for_inst_with_mods() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods]) def module_query_after_inst_create(self): """Check that module-query works on new instance.""" self.test_runner.run_module_query_after_inst_create() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods], runs_after=[module_query_after_inst_create]) def module_retrieve_after_inst_create(self): """Check that module-retrieve works on new instance.""" self.test_runner.run_module_retrieve_after_inst_create() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods], runs_after=[module_retrieve_after_inst_create]) def module_query_after_inst_create_admin(self): """Check that module-query works for admin.""" self.test_runner.run_module_query_after_inst_create_admin() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods], runs_after=[module_query_after_inst_create_admin]) def module_retrieve_after_inst_create_admin(self): """Check that module-retrieve works for admin.""" self.test_runner.run_module_retrieve_after_inst_create_admin() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods], runs_after=[module_retrieve_after_inst_create_admin]) def module_delete_auto_applied(self): """Ensure that module-delete on auto-applied module fails.""" self.test_runner.run_module_delete_auto_applied() - @test(groups=[GROUP, GROUP_INSTANCE_MODULE], + @test(groups=[GROUP, GROUP_MODULE_INSTANCE], depends_on=[wait_for_inst_with_mods], runs_after=[module_delete_auto_applied]) def delete_inst_with_mods(self): @@ -445,7 +452,7 @@ class ModuleDeleteGroup(TestGroup): def __init__(self): super(ModuleDeleteGroup, self).__init__( - 'module_runners', 'ModuleRunner') + ModuleRunnerFactory.instance()) @test(groups=[GROUP, GROUP_MODULE_DELETE]) def module_delete_non_existent(self): diff --git a/trove/tests/scenario/groups/negative_cluster_actions_group.py b/trove/tests/scenario/groups/negative_cluster_actions_group.py index 6257a71307..c89e179268 100644 --- a/trove/tests/scenario/groups/negative_cluster_actions_group.py +++ b/trove/tests/scenario/groups/negative_cluster_actions_group.py @@ -16,17 +16,24 @@ from proboscis import test from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.negative_cluster_actions_group" +class NegativeClusterActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'negative_cluster_actions_runners' + _runner_cls = 'NegativeClusterActionsRunner' + + @test(groups=[GROUP]) class NegativeClusterActionsGroup(TestGroup): def __init__(self): super(NegativeClusterActionsGroup, self).__init__( - 'negative_cluster_actions_runners', 'NegativeClusterActionsRunner') + NegativeClusterActionsRunnerFactory.instance()) @test def create_constrained_size_cluster(self): diff --git a/trove/tests/scenario/groups/replication_group.py b/trove/tests/scenario/groups/replication_group.py index d7b87476c2..1f11dd38a6 100644 --- a/trove/tests/scenario/groups/replication_group.py +++ b/trove/tests/scenario/groups/replication_group.py @@ -17,18 +17,25 @@ from proboscis import test from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.replication_group" +class ReplicationRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'replication_runners' + _runner_cls = 'ReplicationRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class ReplicationGroup(TestGroup): """Test Replication functionality.""" def __init__(self): super(ReplicationGroup, self).__init__( - 'replication_runners', 'ReplicationRunner') + ReplicationRunnerFactory.instance()) @test def add_data_for_replication(self): diff --git a/trove/tests/scenario/groups/root_actions_group.py b/trove/tests/scenario/groups/root_actions_group.py index 7b64ee2343..5a52ba9137 100644 --- a/trove/tests/scenario/groups/root_actions_group.py +++ b/trove/tests/scenario/groups/root_actions_group.py @@ -15,23 +15,29 @@ from proboscis import test +from trove.tests.scenario.groups import backup_group from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.root_actions_group" +class RootActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'root_actions_runners' + _runner_cls = 'RootActionsRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class RootActionsGroup(TestGroup): def __init__(self): super(RootActionsGroup, self).__init__( - 'root_actions_runners', 'RootActionsRunner') - self.backup_runner = self.get_runner( - 'backup_runners', 'BackupRunner') - self.backup_runner2 = self.get_runner( - 'backup_runners', 'BackupRunner') + RootActionsRunnerFactory.instance()) + self.backup_runner = backup_group.BackupRunnerFactory.create() + self.backup_runner2 = backup_group.BackupRunnerFactory.create() @test def check_root_never_enabled(self): diff --git a/trove/tests/scenario/groups/test_group.py b/trove/tests/scenario/groups/test_group.py index d582ce87c6..007c7a183d 100644 --- a/trove/tests/scenario/groups/test_group.py +++ b/trove/tests/scenario/groups/test_group.py @@ -16,92 +16,12 @@ import abc import six -from trove.common.strategies.strategy import Strategy -from trove.tests.config import CONFIG - @six.add_metaclass(abc.ABCMeta) class TestGroup(object): - TEST_RUNNERS_NS = 'trove.tests.scenario.runners' - TEST_HELPERS_NS = 'trove.tests.scenario.helpers' - TEST_HELPER_MODULE_NAME = 'test_helper' - TEST_HELPER_BASE_NAME = 'TestHelper' - - def __init__(self, runner_module_name, runner_base_name, *args, **kwargs): - self._test_runner = self.get_runner( - runner_module_name, runner_base_name, *args, **kwargs) - - def get_runner(self, runner_module_name, runner_base_name, - *args, **kwargs): - class_prefix = self._get_test_datastore() - runner_cls = self._load_dynamic_class( - runner_module_name, class_prefix, runner_base_name, - self.TEST_RUNNERS_NS) - runner = runner_cls(*args, **kwargs) - runner._test_helper = self.get_helper() - return runner - - def get_helper(self): - class_prefix = self._get_test_datastore() - helper_cls = self._load_dynamic_class( - self.TEST_HELPER_MODULE_NAME, class_prefix, - self.TEST_HELPER_BASE_NAME, self.TEST_HELPERS_NS) - return helper_cls(self._build_class_name( - class_prefix, self.TEST_HELPER_BASE_NAME, strip_test=True)) - - def _get_test_datastore(self): - return CONFIG.dbaas_datastore - - def _load_dynamic_class(self, module_name, class_prefix, base_name, - namespace): - """Try to load a datastore specific class if it exists; use the - default otherwise. - """ - # This is for overridden Runner classes - impl = self._build_class_path(module_name, - class_prefix, base_name) - cls = self._load_class('runner', impl, namespace) - - if not cls: - # This is for overridden Helper classes - module = module_name.replace('test', class_prefix.lower()) - impl = self._build_class_path(module, class_prefix, base_name, - strip_test=True) - cls = self._load_class('helper', impl, namespace) - - if not cls: - # Just import the base class - impl = self._build_class_path(module_name, '', base_name) - cls = self._load_class(None, impl, namespace) - - return cls - - def _load_class(self, load_type, impl, namespace): - cls = None - if not load_type or load_type in impl.lower(): - try: - cls = Strategy.get_strategy(impl, namespace) - except ImportError as ie: - # Only fail silently if it's something we expect, - # such as a missing override class. Anything else - # shouldn't be suppressed. - l_msg = ie.message.lower() - if load_type not in l_msg or ( - 'no module named' not in l_msg and - 'cannot be found' not in l_msg): - raise - return cls - - def _build_class_path(self, module_name, class_prefix, class_base, - strip_test=False): - class_name = self._build_class_name(class_prefix, class_base, - strip_test) - return '%s.%s' % (module_name, class_name) - - def _build_class_name(self, class_prefix, base_name, strip_test=False): - base = (base_name.replace('Test', '') if strip_test else base_name) - return '%s%s' % (class_prefix.capitalize(), base) + def __init__(self, test_runner): + self._test_runner = test_runner @property def test_runner(self): diff --git a/trove/tests/scenario/groups/user_actions_group.py b/trove/tests/scenario/groups/user_actions_group.py index a2a7793d68..43933b08a8 100644 --- a/trove/tests/scenario/groups/user_actions_group.py +++ b/trove/tests/scenario/groups/user_actions_group.py @@ -15,23 +15,31 @@ from proboscis import test +from trove.tests.scenario.groups import database_actions_group from trove.tests.scenario.groups import instance_create_group from trove.tests.scenario.groups.test_group import TestGroup +from trove.tests.scenario.runners import test_runners GROUP = "scenario.user_actions_group" +class UserActionsRunnerFactory(test_runners.RunnerFactory): + + _runner_ns = 'user_actions_runners' + _runner_cls = 'UserActionsRunner' + + @test(depends_on_groups=[instance_create_group.GROUP], groups=[GROUP]) class UserActionsGroup(TestGroup): def __init__(self): super(UserActionsGroup, self).__init__( - 'user_actions_runners', 'UserActionsRunner') - self.instance_create_runner = self.get_runner( - 'instance_create_runners', 'InstanceCreateRunner') - self.database_actions_runner = self.get_runner( - 'database_actions_runners', 'DatabaseActionsRunner') + UserActionsRunnerFactory.instance()) + self.instance_create_runner = ( + instance_create_group.InstanceCreateRunnerFactory.create()) + self.database_actions_runner = ( + database_actions_group.DatabaseActionsRunnerFactory.create()) @test def create_initialized_instance(self): diff --git a/trove/tests/scenario/helpers/mysql_helper.py b/trove/tests/scenario/helpers/mysql_helper.py index b52092b9a8..a8fc46c718 100644 --- a/trove/tests/scenario/helpers/mysql_helper.py +++ b/trove/tests/scenario/helpers/mysql_helper.py @@ -33,11 +33,11 @@ class MysqlHelper(SqlHelper): {'name': 'db2'}, {"name": 'db3'}] def get_valid_user_definitions(self): - return [{'name': 'user1', 'password': 'password1', 'databases': [], + return [{'name': 'a_user1', 'password': 'password1', 'databases': [], 'host': '127.0.0.1'}, - {'name': 'user2', 'password': 'password1', + {'name': 'a_user2', 'password': 'password1', 'databases': [{'name': 'db1'}], 'host': '0.0.0.0'}, - {'name': 'user3', 'password': 'password1', + {'name': 'a_user3', 'password': 'password1', 'databases': [{'name': 'db1'}, {'name': 'db2'}]}] def get_dynamic_group(self): diff --git a/trove/tests/scenario/runners/configuration_runners.py b/trove/tests/scenario/runners/configuration_runners.py index 420a43648e..33a4190388 100644 --- a/trove/tests/scenario/runners/configuration_runners.py +++ b/trove/tests/scenario/runners/configuration_runners.py @@ -18,12 +18,9 @@ import json from proboscis import SkipTest from trove.common.utils import generate_uuid -from trove.tests.config import CONFIG from trove.tests.scenario.runners.test_runners import TestRunner from trove.tests.util.check import CollectionCheck from trove.tests.util.check import TypeCheck -from trove.tests.util import create_dbaas_client -from trove.tests.util.users import Requirements from troveclient.compat import exceptions @@ -39,7 +36,6 @@ class ConfigurationRunner(TestRunner): self.non_dynamic_inst_count = 0 self.initial_group_count = 0 self.additional_group_count = 0 - self.other_client = None self.config_id_for_inst = None self.config_inst_id = None @@ -273,20 +269,12 @@ class ConfigurationRunner(TestRunner): def assert_conf_get_unauthorized_user( self, config_id, expected_exception=exceptions.NotFound, expected_http_code=404): - self._create_other_client() self.assert_raises( expected_exception, None, - self.other_client.configurations.get, config_id) + self.unauth_client.configurations.get, config_id) # we're using a different client, so we'll check the return code # on it explicitly, instead of depending on 'assert_raises' - self.assert_client_code(expected_http_code, client=self.other_client) - - def _create_other_client(self): - if not self.other_client: - requirements = Requirements(is_admin=False) - other_user = CONFIG.users.find_user( - requirements, black_list=[self.instance_info.user.auth_user]) - self.other_client = create_dbaas_client(other_user) + self.assert_client_code(expected_http_code, client=self.unauth_client) def run_non_dynamic_conf_get_unauthorized_user( self, expected_exception=exceptions.NotFound, diff --git a/trove/tests/scenario/runners/instance_create_runners.py b/trove/tests/scenario/runners/instance_create_runners.py index 23c691eccf..97f811a363 100644 --- a/trove/tests/scenario/runners/instance_create_runners.py +++ b/trove/tests/scenario/runners/instance_create_runners.py @@ -17,9 +17,10 @@ import json from proboscis import SkipTest -from trove.tests.api.instances import CheckInstance, InstanceTestInfo from trove.tests.config import CONFIG from trove.tests.scenario.helpers.test_helper import DataType +from trove.tests.scenario.runners.test_runners import CheckInstance +from trove.tests.scenario.runners.test_runners import InstanceTestInfo from trove.tests.scenario.runners.test_runners import TestRunner @@ -32,7 +33,8 @@ class InstanceCreateRunner(TestRunner): self.init_inst_users = None self.init_inst_host = None self.init_inst_data = None - self.init_config_group_id = None + self.init_inst_config_group_id = None + self.config_group_id = None def run_empty_instance_create( self, expected_states=['BUILD', 'ACTIVE'], expected_http_code=200): @@ -40,20 +42,21 @@ class InstanceCreateRunner(TestRunner): flavor = self._get_instance_flavor() trove_volume_size = CONFIG.get('trove_volume_size', 1) - info = self.assert_instance_create( + instance_info = self.assert_instance_create( name, flavor, trove_volume_size, [], [], None, None, CONFIG.dbaas_datastore, CONFIG.dbaas_datastore_version, expected_states, expected_http_code, create_helper_user=True) # Update the shared instance info. - self.instance_info.databases = info.databases - self.instance_info.users = info.users - self.instance_info.dbaas_datastore = info.dbaas_datastore - self.instance_info.dbaas_datastore_version = (info. - dbaas_datastore_version) - self.instance_info.dbaas_flavor_href = info.dbaas_flavor_href - self.instance_info.volume = info.volume - self.instance_info.id = info.id + self.instance_info.id = instance_info.id + self.instance_info.name = instance_info.name + self.instance_info.databases = instance_info.databases + self.instance_info.users = instance_info.users + self.instance_info.dbaas_datastore = instance_info.dbaas_datastore + self.instance_info.dbaas_datastore_version = ( + instance_info.dbaas_datastore_version) + self.instance_info.dbaas_flavor_href = instance_info.dbaas_flavor_href + self.instance_info.volume = instance_info.volume def run_initial_configuration_create(self, expected_http_code=200): dynamic_config = self.test_helper.get_dynamic_group() @@ -69,7 +72,7 @@ class InstanceCreateRunner(TestRunner): datastore_version=self.instance_info.dbaas_datastore_version) self.assert_client_code(expected_http_code) - self.init_config_group_id = result.id + self.config_group_id = result.id else: raise SkipTest("No groups defined.") @@ -83,6 +86,7 @@ class InstanceCreateRunner(TestRunner): # test instances. raise SkipTest("Using an existing instance.") + configuration_id = configuration_id or self.config_group_id name = self.instance_info.name + '_init' flavor = self._get_instance_flavor() trove_volume_size = CONFIG.get('trove_volume_size', 1) @@ -90,15 +94,12 @@ class InstanceCreateRunner(TestRunner): if with_dbs else []) self.init_inst_users = (self.test_helper.get_valid_user_definitions() if with_users else []) - if configuration_id: - self.init_config_group_id = configuration_id - - if (self.init_inst_dbs or self.init_inst_users or - self.init_config_group_id): + self.init_inst_config_group_id = configuration_id + if (self.init_inst_dbs or self.init_inst_users or configuration_id): info = self.assert_instance_create( name, flavor, trove_volume_size, self.init_inst_dbs, self.init_inst_users, - self.init_config_group_id, None, + configuration_id, None, CONFIG.dbaas_datastore, CONFIG.dbaas_datastore_version, expected_states, expected_http_code, create_helper_user=create_helper_user) @@ -244,7 +245,7 @@ class InstanceCreateRunner(TestRunner): if self.init_inst_id: self.assert_instance_properties( self.init_inst_id, self.init_inst_dbs, self.init_inst_users, - self.init_config_group_id, self.init_inst_data) + self.init_inst_config_group_id, self.init_inst_data) def assert_instance_properties( self, instance_id, expected_dbs_definitions, @@ -316,10 +317,17 @@ class InstanceCreateRunner(TestRunner): self.assert_all_gone(self.init_inst_id, expected_states[-1]) else: raise SkipTest("Cleanup is not required.") + self.init_inst_id = None + self.init_inst_dbs = None + self.init_inst_users = None + self.init_inst_host = None + self.init_inst_data = None + self.init_inst_config_group_id = None def run_initial_configuration_delete(self, expected_http_code=202): - if self.init_config_group_id: - self.auth_client.configurations.delete(self.init_config_group_id) + if self.config_group_id: + self.auth_client.configurations.delete(self.config_group_id) self.assert_client_code(expected_http_code) else: raise SkipTest("Cleanup is not required.") + self.config_group_id = None diff --git a/trove/tests/scenario/runners/module_runners.py b/trove/tests/scenario/runners/module_runners.py index 96cad31461..5b54216984 100644 --- a/trove/tests/scenario/runners/module_runners.py +++ b/trove/tests/scenario/runners/module_runners.py @@ -26,27 +26,6 @@ from trove.module import models from trove.tests.scenario.runners.test_runners import TestRunner -# Variables here are set up to be used across multiple groups, -# since each group will instantiate a new runner -random_data = Crypto.Random.new().read(20) -test_modules = [] -module_count_prior_to_create = 0 -module_ds_count_prior_to_create = 0 -module_ds_all_count_prior_to_create = 0 -module_all_tenant_count_prior_to_create = 0 -module_auto_apply_count_prior_to_create = 0 -module_admin_count_prior_to_create = 0 -module_other_count_prior_to_create = 0 - -module_create_count = 0 -module_ds_create_count = 0 -module_ds_all_create_count = 0 -module_all_tenant_create_count = 0 -module_auto_apply_create_count = 0 -module_admin_create_count = 0 -module_other_create_count = 0 - - class ModuleRunner(TestRunner): def __init__(self): @@ -62,13 +41,30 @@ class ModuleRunner(TestRunner): self.MODULE_NEG_CONTENTS = 'contents for negative tests' self.MODULE_BINARY_SUFFIX = '_bin_auto' self.MODULE_BINARY_SUFFIX2 = self.MODULE_BINARY_SUFFIX + '_2' - self.MODULE_BINARY_CONTENTS = random_data + self.MODULE_BINARY_CONTENTS = Crypto.Random.new().read(20) self.MODULE_BINARY_CONTENTS2 = '\x00\xFF\xea\x9c\x11\xfeok\xb1\x8ax' self.mod_inst_id = None self.temp_module = None self._module_type = None + self.test_modules = [] + self.module_count_prior_to_create = 0 + self.module_ds_count_prior_to_create = 0 + self.module_ds_all_count_prior_to_create = 0 + self.module_all_tenant_count_prior_to_create = 0 + self.module_auto_apply_count_prior_to_create = 0 + self.module_admin_count_prior_to_create = 0 + self.module_other_count_prior_to_create = 0 + + self.module_create_count = 0 + self.module_ds_create_count = 0 + self.module_ds_all_create_count = 0 + self.module_all_tenant_create_count = 0 + self.module_auto_apply_create_count = 0 + self.module_admin_create_count = 0 + self.module_other_create_count = 0 + @property def module_type(self): if not self._module_type: @@ -77,9 +73,9 @@ class ModuleRunner(TestRunner): @property def main_test_module(self): - if not test_modules or not test_modules[0]: + if not self.test_modules or not self.test_modules[0]: SkipTest("No main module created") - return test_modules[0] + return self.test_modules[0] def build_module_args(self, extra=None): extra = extra or '' @@ -103,7 +99,7 @@ class ModuleRunner(TestRunner): def _find_module(self, match_fn, not_found_message, find_all=False): found = [] if find_all else None - for test_module in test_modules: + for test_module in self.test_modules: if match_fn(test_module): if find_all: found.append(test_module) @@ -203,29 +199,22 @@ class ModuleRunner(TestRunner): def run_module_create(self): # Necessary to test that the count increases. - global module_count_prior_to_create - global module_ds_count_prior_to_create - global module_ds_all_count_prior_to_create - global module_all_tenant_count_prior_to_create - global module_auto_apply_count_prior_to_create - global module_admin_count_prior_to_create - global module_other_count_prior_to_create - module_count_prior_to_create = len( + self.module_count_prior_to_create = len( self.auth_client.modules.list()) - module_ds_count_prior_to_create = len( + self.module_ds_count_prior_to_create = len( self.auth_client.modules.list( datastore=self.instance_info.dbaas_datastore)) - module_ds_all_count_prior_to_create = len( + self.module_ds_all_count_prior_to_create = len( self.auth_client.modules.list( datastore=models.Modules.MATCH_ALL_NAME)) - module_all_tenant_count_prior_to_create = len( + self.module_all_tenant_count_prior_to_create = len( self.unauth_client.modules.list()) - module_auto_apply_count_prior_to_create = len( + self.module_auto_apply_count_prior_to_create = len( [module for module in self.admin_client.modules.list() if module.auto_apply]) - module_admin_count_prior_to_create = len( + self.module_admin_count_prior_to_create = len( self.admin_client.modules.list()) - module_other_count_prior_to_create = len( + self.module_other_count_prior_to_create = len( self.unauth_client.modules.list()) name, description, contents = self.build_module_args() self.assert_module_create( @@ -248,30 +237,22 @@ class ModuleRunner(TestRunner): datastore=datastore, datastore_version=datastore_version, auto_apply=auto_apply, live_update=live_update, visible=visible) - global module_create_count - global module_ds_create_count - global module_ds_all_create_count - global module_auto_apply_create_count - global module_all_tenant_create_count - global module_admin_create_count - global module_other_create_count if (client == self.auth_client or (client == self.admin_client and visible)): - module_create_count += 1 + self.module_create_count += 1 if datastore: - module_ds_create_count += 1 + self.module_ds_create_count += 1 else: - module_ds_all_create_count += 1 + self.module_ds_all_create_count += 1 elif not visible: - module_admin_create_count += 1 + self.module_admin_create_count += 1 else: - module_other_create_count += 1 + self.module_other_create_count += 1 if all_tenants and visible: - module_all_tenant_create_count += 1 + self.module_all_tenant_create_count += 1 if auto_apply and visible: - module_auto_apply_create_count += 1 - global test_modules - test_modules.append(result) + self.module_auto_apply_create_count += 1 + self.test_modules.append(result) tenant_id = None tenant = models.Modules.MATCH_ALL_NAME @@ -413,7 +394,7 @@ class ModuleRunner(TestRunner): def run_module_list(self): self.assert_module_list( self.auth_client, - module_count_prior_to_create + module_create_count) + self.module_count_prior_to_create + self.module_create_count) def assert_module_list(self, client, expected_count, datastore=None, skip_validation=False): @@ -441,8 +422,9 @@ class ModuleRunner(TestRunner): def run_module_list_unauth_user(self): self.assert_module_list( self.unauth_client, - module_all_tenant_count_prior_to_create + - module_all_tenant_create_count + module_other_create_count) + (self.module_all_tenant_count_prior_to_create + + self.module_all_tenant_create_count + + self.module_other_create_count)) def run_module_create_admin_all(self): name, description, contents = self.build_module_args( @@ -517,20 +499,21 @@ class ModuleRunner(TestRunner): def run_module_list_again(self): self.assert_module_list( self.auth_client, - module_count_prior_to_create + module_create_count, + self.module_count_prior_to_create + self.module_create_count, skip_validation=True) def run_module_list_ds(self): self.assert_module_list( self.auth_client, - module_ds_count_prior_to_create + module_ds_create_count, + self.module_ds_count_prior_to_create + self.module_ds_create_count, datastore=self.instance_info.dbaas_datastore, skip_validation=True) def run_module_list_ds_all(self): self.assert_module_list( self.auth_client, - module_ds_all_count_prior_to_create + module_ds_all_create_count, + (self.module_ds_all_count_prior_to_create + + self.module_ds_all_create_count), datastore=models.Modules.MATCH_ALL_NAME, skip_validation=True) @@ -545,10 +528,10 @@ class ModuleRunner(TestRunner): def run_module_list_admin(self): self.assert_module_list( self.admin_client, - (module_admin_count_prior_to_create + - module_create_count + - module_admin_create_count + - module_other_create_count), + (self.module_admin_count_prior_to_create + + self.module_create_count + + self.module_admin_create_count + + self.module_other_create_count), skip_validation=True) def run_module_update(self): @@ -599,17 +582,16 @@ class ModuleRunner(TestRunner): def assert_module_update(self, client, module_id, **kwargs): result = client.modules.update(module_id, **kwargs) - global test_modules found = False index = -1 - for test_module in test_modules: + for test_module in self.test_modules: index += 1 if test_module.id == module_id: found = True break if not found: self.fail("Could not find updated module in module list") - test_modules[index] = result + self.test_modules[index] = result expected_args = {} for key, value in kwargs.items(): @@ -701,7 +683,7 @@ class ModuleRunner(TestRunner): def run_module_list_instance_empty(self): self.assert_module_list_instance( self.auth_client, self.instance_info.id, - module_auto_apply_count_prior_to_create) + self.module_auto_apply_count_prior_to_create) def assert_module_list_instance(self, client, instance_id, expected_count, expected_http_code=200): @@ -728,7 +710,7 @@ class ModuleRunner(TestRunner): def run_module_query_empty(self): self.assert_module_query(self.auth_client, self.instance_info.id, - module_auto_apply_count_prior_to_create) + self.module_auto_apply_count_prior_to_create) def assert_module_query(self, client, instance_id, expected_count, expected_http_code=200, expected_results=None): @@ -826,7 +808,7 @@ class ModuleRunner(TestRunner): self.auth_client, self.instance_info.id, 1) def run_module_query_after_apply(self): - expected_count = module_auto_apply_count_prior_to_create + 1 + expected_count = self.module_auto_apply_count_prior_to_create + 1 expected_results = self.create_default_query_expected_results( [self.main_test_module]) self.assert_module_query(self.auth_client, self.instance_info.id, @@ -1029,23 +1011,23 @@ class ModuleRunner(TestRunner): def run_module_delete(self): expected_count = len(self.auth_client.modules.list()) - 1 - test_module = test_modules.pop(0) + test_module = self.test_modules.pop(0) self.assert_module_delete(self.auth_client, test_module.id, expected_count) def run_module_delete_admin(self): start_count = count = len(self.admin_client.modules.list()) - for test_module in test_modules: + for test_module in self.test_modules: count -= 1 self.report.log("Deleting module '%s' (tenant: %s)" % ( test_module.name, test_module.tenant_id)) self.assert_module_delete(self.admin_client, test_module.id, count) self.assert_not_equal(start_count, count, "Nothing was deleted") count = len(self.admin_client.modules.list()) - self.assert_equal(module_admin_count_prior_to_create, count, + self.assert_equal(self.module_admin_count_prior_to_create, count, "Wrong number of admin modules after deleting all") count = len(self.auth_client.modules.list()) - self.assert_equal(module_count_prior_to_create, count, + self.assert_equal(self.module_count_prior_to_create, count, "Wrong number of modules after deleting all") def assert_module_delete(self, client, module_id, expected_count): diff --git a/trove/tests/scenario/runners/replication_runners.py b/trove/tests/scenario/runners/replication_runners.py index bdfe9534e4..d39b906f57 100644 --- a/trove/tests/scenario/runners/replication_runners.py +++ b/trove/tests/scenario/runners/replication_runners.py @@ -14,8 +14,8 @@ # under the License. from trove.common import utils -from trove.tests.api.instances import CheckInstance from trove.tests.scenario.helpers.test_helper import DataType +from trove.tests.scenario.runners.test_runners import CheckInstance from trove.tests.scenario.runners.test_runners import TestRunner from troveclient.compat import exceptions diff --git a/trove/tests/scenario/runners/test_runners.py b/trove/tests/scenario/runners/test_runners.py index 1f9a6d7b2f..0e553ae84d 100644 --- a/trove/tests/scenario/runners/test_runners.py +++ b/trove/tests/scenario/runners/test_runners.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime import os import time as timer @@ -23,15 +24,137 @@ from troveclient.compat import exceptions from trove.common import cfg from trove.common import exception +from trove.common.strategies.strategy import Strategy from trove.common import utils from trove.common.utils import poll_until, build_polling_task -from trove.tests.api.instances import instance_info from trove.tests.config import CONFIG +from trove.tests.util.check import AttrCheck from trove.tests.util import create_dbaas_client from trove.tests.util.users import Requirements CONF = cfg.CONF +TEST_RUNNERS_NS = 'trove.tests.scenario.runners' +TEST_HELPERS_NS = 'trove.tests.scenario.helpers' +TEST_HELPER_MODULE_NAME = 'test_helper' +TEST_HELPER_BASE_NAME = 'TestHelper' + + +class RunnerFactory(object): + + _test_runner = None + _runner_ns = None + _runner_cls = None + + @classmethod + def instance(cls): + """Returns the current instance of the runner, or creates a new + one if none exists. This is useful to have multiple 'group' classes + use the same runner so that state is maintained. + """ + if not cls._test_runner: + cls._test_runner = cls.create() + return cls._test_runner + + @classmethod + def create(cls): + """Returns a new instance of the runner. Tests that require a 'fresh' + runner (typically from a different 'group') can call this. + """ + return cls._get_runner(cls._runner_ns, cls._runner_cls) + + @classmethod + def _get_runner(cls, runner_module_name, runner_base_name, + *args, **kwargs): + class_prefix = cls._get_test_datastore() + runner_cls = cls._load_dynamic_class( + runner_module_name, class_prefix, runner_base_name, + TEST_RUNNERS_NS) + runner = runner_cls(*args, **kwargs) + runner._test_helper = cls._get_helper() + return runner + + @classmethod + def _get_helper(cls): + class_prefix = cls._get_test_datastore() + helper_cls = cls._load_dynamic_class( + TEST_HELPER_MODULE_NAME, class_prefix, + TEST_HELPER_BASE_NAME, TEST_HELPERS_NS) + return helper_cls(cls._build_class_name( + class_prefix, TEST_HELPER_BASE_NAME, strip_test=True)) + + @classmethod + def _get_test_datastore(cls): + return CONFIG.dbaas_datastore + + @classmethod + def _load_dynamic_class(cls, module_name, class_prefix, base_name, + namespace): + """Try to load a datastore specific class if it exists; use the + default otherwise. + """ + # This is for overridden Runner classes + impl = cls._build_class_path(module_name, class_prefix, base_name) + clazz = cls._load_class('runner', impl, namespace) + + if not clazz: + # This is for overridden Helper classes + module = module_name.replace('test', class_prefix.lower()) + impl = cls._build_class_path( + module, class_prefix, base_name, strip_test=True) + clazz = cls._load_class('helper', impl, namespace) + + if not clazz: + # Just import the base class + impl = cls._build_class_path(module_name, '', base_name) + clazz = cls._load_class(None, impl, namespace) + + return clazz + + @classmethod + def _load_class(cls, load_type, impl, namespace): + clazz = None + if not load_type or load_type in impl.lower(): + try: + clazz = Strategy.get_strategy(impl, namespace) + except ImportError as ie: + # Only fail silently if it's something we expect, + # such as a missing override class. Anything else + # shouldn't be suppressed. + l_msg = ie.message.lower() + if load_type not in l_msg or ( + 'no module named' not in l_msg and + 'cannot be found' not in l_msg): + raise + return clazz + + @classmethod + def _build_class_path(cls, module_name, class_prefix, class_base, + strip_test=False): + class_name = cls._build_class_name( + class_prefix, class_base, strip_test) + return '%s.%s' % (module_name, class_name) + + @classmethod + def _build_class_name(cls, class_prefix, base_name, strip_test=False): + base = (base_name.replace('Test', '') if strip_test else base_name) + return '%s%s' % (class_prefix.capitalize(), base) + + +class InstanceTestInfo(object): + """Stores new instance information used by dependent tests.""" + + def __init__(self): + self.id = None # The ID of the instance in the database. + self.name = None # Test name, generated each test run. + self.dbaas_flavor_href = None # The flavor of the instance. + self.dbaas_datastore = None # The datastore id + self.dbaas_datastore_version = None # The datastore version id + self.volume = None # The volume the instance will have. + self.nics = None # The dict of type/id for nics used on the intance. + self.user = None # The user instance who owns the instance. + self.users = None # The users created on the instance. + class TestRunner(object): @@ -64,21 +187,27 @@ class TestRunner(object): EPHEMERAL_SUPPORT = not VOLUME_SUPPORT and CONFIG.get('device_path', None) ROOT_PARTITION = not (VOLUME_SUPPORT or CONFIG.get('device_path', None)) + # Here's where the info for the 'main' test instance goes + instance_info = InstanceTestInfo() report = CONFIG.get_report() def __init__(self, sleep_time=10, timeout=1200): self.def_sleep_time = sleep_time self.def_timeout = timeout - self.instance_info = instance_info - instance_info.dbaas_datastore = CONFIG.dbaas_datastore - instance_info.dbaas_datastore_version = CONFIG.dbaas_datastore_version + self.instance_info.name = "TEST_" + datetime.datetime.strftime( + datetime.datetime.now(), '%Y-%m-%d_%H:%M:%S') + self.instance_info.dbaas_datastore = CONFIG.dbaas_datastore + self.instance_info.dbaas_datastore_version = ( + CONFIG.dbaas_datastore_version) + self.instance_info.user = CONFIG.users.find_user_by_name('alt_demo') if self.VOLUME_SUPPORT: - instance_info.volume = {'size': CONFIG.get('trove_volume_size', 1)} + self.instance_info.volume = { + 'size': CONFIG.get('trove_volume_size', 1)} else: - instance_info.volume = None + self.instance_info.volume = None - self.auth_client = create_dbaas_client(self.instance_info.user) + self._auth_client = None self._unauth_client = None self._admin_client = None self._swift_client = None @@ -151,6 +280,16 @@ class TestRunner(object): def test_helper(self, test_helper): self._test_helper = test_helper + @property + def auth_client(self): + if not self._auth_client: + self._auth_client = self._create_authorized_client() + return self._auth_client + + def _create_authorized_client(self): + """Create a client from the normal 'authorized' user.""" + return create_dbaas_client(self.instance_info.user) + @property def unauth_client(self): if not self._unauth_client: @@ -223,7 +362,11 @@ class TestRunner(object): @property def is_using_existing_instance(self): - return self.has_env_flag(self.USE_INSTANCE_ID_FLAG) + return TestRunner.using_existing_instance() + + @staticmethod + def using_existing_instance(): + return TestRunner.has_env_flag(TestRunner.USE_INSTANCE_ID_FLAG) @staticmethod def has_env_flag(flag_name): @@ -449,3 +592,114 @@ class TestRunner(object): return (database_def, _get_credentials(credentials), _get_credentials(credentials_root)) + + +class CheckInstance(AttrCheck): + """Class to check various attributes of Instance details.""" + + def __init__(self, instance): + super(CheckInstance, self).__init__() + self.instance = instance + self.volume_support = TestRunner.VOLUME_SUPPORT + self.existing_instance = TestRunner.is_using_existing_instance + + def flavor(self): + if 'flavor' not in self.instance: + self.fail("'flavor' not found in instance.") + else: + allowed_attrs = ['id', 'links'] + self.contains_allowed_attrs( + self.instance['flavor'], allowed_attrs, + msg="Flavor") + self.links(self.instance['flavor']['links']) + + def datastore(self): + if 'datastore' not in self.instance: + self.fail("'datastore' not found in instance.") + else: + allowed_attrs = ['type', 'version'] + self.contains_allowed_attrs( + self.instance['datastore'], allowed_attrs, + msg="datastore") + + def volume_key_exists(self): + if 'volume' not in self.instance: + self.fail("'volume' not found in instance.") + return False + return True + + def volume(self): + if not self.volume_support: + return + if self.volume_key_exists(): + allowed_attrs = ['size'] + if self.existing_instance: + allowed_attrs.append('used') + self.contains_allowed_attrs( + self.instance['volume'], allowed_attrs, + msg="Volumes") + + def used_volume(self): + if not self.volume_support: + return + if self.volume_key_exists(): + allowed_attrs = ['size', 'used'] + print(self.instance) + self.contains_allowed_attrs( + self.instance['volume'], allowed_attrs, + msg="Volumes") + + def volume_mgmt(self): + if not self.volume_support: + return + if self.volume_key_exists(): + allowed_attrs = ['description', 'id', 'name', 'size'] + self.contains_allowed_attrs( + self.instance['volume'], allowed_attrs, + msg="Volumes") + + def addresses(self): + allowed_attrs = ['addr', 'version'] + print(self.instance) + networks = ['usernet'] + for network in networks: + for address in self.instance['addresses'][network]: + self.contains_allowed_attrs( + address, allowed_attrs, + msg="Address") + + def guest_status(self): + allowed_attrs = ['created_at', 'deleted', 'deleted_at', 'instance_id', + 'state', 'state_description', 'updated_at'] + self.contains_allowed_attrs( + self.instance['guest_status'], allowed_attrs, + msg="Guest status") + + def mgmt_volume(self): + if not self.volume_support: + return + allowed_attrs = ['description', 'id', 'name', 'size'] + self.contains_allowed_attrs( + self.instance['volume'], allowed_attrs, + msg="Volume") + + def replica_of(self): + if 'replica_of' not in self.instance: + self.fail("'replica_of' not found in instance.") + else: + allowed_attrs = ['id', 'links'] + self.contains_allowed_attrs( + self.instance['replica_of'], allowed_attrs, + msg="Replica-of links not found") + self.links(self.instance['replica_of']['links']) + + def slaves(self): + if 'replicas' not in self.instance: + self.fail("'replicas' not found in instance.") + else: + allowed_attrs = ['id', 'links'] + for slave in self.instance['replicas']: + self.contains_allowed_attrs( + slave, allowed_attrs, + msg="Replica links not found") + self.links(slave['links'])