summaryrefslogtreecommitdiff
path: root/trove/tests/scenario/runners/cluster_runners.py
diff options
context:
space:
mode:
Diffstat (limited to 'trove/tests/scenario/runners/cluster_runners.py')
-rw-r--r--trove/tests/scenario/runners/cluster_runners.py238
1 files changed, 233 insertions, 5 deletions
diff --git a/trove/tests/scenario/runners/cluster_runners.py b/trove/tests/scenario/runners/cluster_runners.py
index d9a0f153..8c652ec6 100644
--- a/trove/tests/scenario/runners/cluster_runners.py
+++ b/trove/tests/scenario/runners/cluster_runners.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
import os
from proboscis import SkipTest
@@ -49,6 +50,11 @@ class ClusterRunner(TestRunner):
self.initial_instance_count = None
self.cluster_instances = None
self.cluster_removed_instances = None
+ self.active_config_group_id = None
+ self.config_requires_restart = False
+ self.initial_group_id = None
+ self.dynamic_group_id = None
+ self.non_dynamic_group_id = None
@property
def is_using_existing_cluster(self):
@@ -62,6 +68,15 @@ class ClusterRunner(TestRunner):
def min_cluster_node_count(self):
return 2
+ def run_initial_configuration_create(self, expected_http_code=200):
+ group_id, requires_restart = self.create_initial_configuration(
+ expected_http_code)
+ if group_id:
+ self.initial_group_id = group_id
+ self.config_requires_restart = requires_restart
+ else:
+ raise SkipTest("No groups defined.")
+
def run_cluster_create(self, num_nodes=None, expected_task_name='BUILDING',
expected_http_code=200):
self.cluster_count_before_create = len(
@@ -84,11 +99,11 @@ class ClusterRunner(TestRunner):
self.cluster_id = self.assert_cluster_create(
self.cluster_name, instance_defs, self.locality,
- expected_task_name, expected_http_code)
+ self.initial_group_id, expected_task_name, expected_http_code)
def assert_cluster_create(
- self, cluster_name, instances_def, locality, expected_task_name,
- expected_http_code):
+ self, cluster_name, instances_def, locality, configuration,
+ expected_task_name, expected_http_code):
self.report.log("Testing cluster create: %s" % cluster_name)
@@ -100,8 +115,10 @@ class ClusterRunner(TestRunner):
cluster = client.clusters.create(
cluster_name, self.instance_info.dbaas_datastore,
self.instance_info.dbaas_datastore_version,
- instances=instances_def, locality=locality)
+ instances=instances_def, locality=locality,
+ configuration=configuration)
self.assert_client_code(client, expected_http_code)
+ self.active_config_group_id = configuration
self._assert_cluster_values(cluster, expected_task_name)
for instance in cluster.instances:
self.register_debug_inst_ids(instance['id'])
@@ -202,7 +219,8 @@ class ClusterRunner(TestRunner):
self.current_root_creds = client.root.create_cluster_root(
self.cluster_id, root_credentials['password'])
self.assert_client_code(client, expected_http_code)
- self._assert_cluster_response(client, cluster_id, expected_task_name)
+ self._assert_cluster_response(
+ client, self.cluster_id, expected_task_name)
self.assert_equal(root_credentials['name'],
self.current_root_creds[0])
self.assert_equal(root_credentials['password'],
@@ -506,6 +524,8 @@ class ClusterRunner(TestRunner):
check.has_field("updated", six.text_type)
if check_locality:
check.has_field("locality", six.text_type)
+ if self.active_config_group_id:
+ check.has_field("configuration", six.text_type)
for instance in cluster.instances:
isinstance(instance, dict)
self.assert_is_not_none(instance['id'])
@@ -528,6 +548,214 @@ class ClusterRunner(TestRunner):
except exceptions.NotFound:
self.assert_client_code(client, 404)
+ def restart_after_configuration_change(self):
+ if self.config_requires_restart:
+ self.run_cluster_restart()
+ self.run_cluster_restart_wait()
+ self.config_requires_restart = False
+ else:
+ raise SkipTest("Not required.")
+
+ def run_create_dynamic_configuration(self, expected_http_code=200):
+ values = self.test_helper.get_dynamic_group()
+ if values:
+ self.dynamic_group_id = self.assert_create_group(
+ 'dynamic_cluster_test_group',
+ 'a fully dynamic group should not require restart',
+ values, expected_http_code)
+ elif values is None:
+ raise SkipTest("No dynamic group defined in %s." %
+ self.test_helper.get_class_name())
+ else:
+ raise SkipTest("Datastore has no dynamic configuration values.")
+
+ def assert_create_group(self, name, description, values,
+ expected_http_code):
+ json_def = json.dumps(values)
+ client = self.auth_client
+ result = client.configurations.create(
+ name,
+ json_def,
+ description,
+ datastore=self.instance_info.dbaas_datastore,
+ datastore_version=self.instance_info.dbaas_datastore_version)
+ self.assert_client_code(client, expected_http_code)
+
+ return result.id
+
+ def run_create_non_dynamic_configuration(self, expected_http_code=200):
+ values = self.test_helper.get_non_dynamic_group()
+ if values:
+ self.non_dynamic_group_id = self.assert_create_group(
+ 'non_dynamic_cluster_test_group',
+ 'a group containing non-dynamic properties should always '
+ 'require restart',
+ values, expected_http_code)
+ elif values is None:
+ raise SkipTest("No non-dynamic group defined in %s." %
+ self.test_helper.get_class_name())
+ else:
+ raise SkipTest("Datastore has no non-dynamic configuration "
+ "values.")
+
+ def run_attach_dynamic_configuration(
+ self, expected_states=['NONE'],
+ expected_http_code=202):
+ if self.dynamic_group_id:
+ self.assert_attach_configuration(
+ self.cluster_id, self.dynamic_group_id, expected_states,
+ expected_http_code)
+
+ def assert_attach_configuration(
+ self, cluster_id, group_id, expected_states, expected_http_code,
+ restart_inst=False):
+ client = self.auth_client
+ client.clusters.configuration_attach(cluster_id, group_id)
+ self.assert_client_code(client, expected_http_code)
+ self.active_config_group_id = group_id
+ self._assert_cluster_states(client, cluster_id, expected_states)
+ self.assert_configuration_group(client, cluster_id, group_id)
+
+ if restart_inst:
+ self.config_requires_restart = True
+ cluster_instances = self._get_cluster_instances(cluster_id)
+ for node in cluster_instances:
+ self.assert_equal(
+ 'RESTART_REQUIRED', node.status,
+ "Node '%s' should be in 'RESTART_REQUIRED' state."
+ % node.id)
+
+ def assert_configuration_group(
+ self, client, cluster_id, expected_group_id):
+ cluster = client.clusters.get(cluster_id)
+ self.assert_equal(
+ expected_group_id, cluster.configuration,
+ "Attached group does not have the expected ID.")
+
+ cluster_instances = self._get_cluster_instances(client, cluster_id)
+ for node in cluster_instances:
+ self.assert_equal(
+ expected_group_id, cluster.configuration,
+ "Attached group does not have the expected ID on "
+ "cluster node: %s" % node.id)
+
+ def run_attach_non_dynamic_configuration(
+ self, expected_states=['NONE'],
+ expected_http_code=202):
+ if self.non_dynamic_group_id:
+ self.assert_attach_configuration(
+ self.cluster_id, self.non_dynamic_group_id,
+ expected_states, expected_http_code, restart_inst=True)
+
+ def run_verify_initial_configuration(self):
+ if self.initial_group_id:
+ self.verify_configuration(self.cluster_id, self.initial_group_id)
+
+ def verify_configuration(self, cluster_id, expected_group_id):
+ self.assert_configuration_group(cluster_id, expected_group_id)
+ self.assert_configuration_values(cluster_id, expected_group_id)
+
+ def assert_configuration_values(self, cluster_id, group_id):
+ if group_id == self.initial_group_id:
+ if not self.config_requires_restart:
+ expected_configs = self.test_helper.get_dynamic_group()
+ else:
+ expected_configs = self.test_helper.get_non_dynamic_group()
+ if group_id == self.dynamic_group_id:
+ expected_configs = self.test_helper.get_dynamic_group()
+ elif group_id == self.non_dynamic_group_id:
+ expected_configs = self.test_helper.get_non_dynamic_group()
+
+ self._assert_configuration_values(cluster_id, expected_configs)
+
+ def _assert_configuration_values(self, cluster_id, expected_configs):
+ cluster_instances = self._get_cluster_instances(cluster_id)
+ for node in cluster_instances:
+ host = self.get_instance_host(node)
+ self.report.log(
+ "Verifying cluster configuration via node: %s" % host)
+ for name, value in expected_configs.items():
+ actual = self.test_helper.get_configuration_value(name, host)
+ self.assert_equal(str(value), str(actual),
+ "Unexpected value of property '%s'" % name)
+
+ def run_verify_dynamic_configuration(self):
+ if self.dynamic_group_id:
+ self.verify_configuration(self.cluster_id, self.dynamic_group_id)
+
+ def run_verify_non_dynamic_configuration(self):
+ if self.non_dynamic_group_id:
+ self.verify_configuration(
+ self.cluster_id, self.non_dynamic_group_id)
+
+ def run_detach_initial_configuration(self, expected_states=['NONE'],
+ expected_http_code=202):
+ if self.initial_group_id:
+ self.assert_detach_configuration(
+ self.cluster_id, expected_states, expected_http_code,
+ restart_inst=self.config_requires_restart)
+
+ def run_detach_dynamic_configuration(self, expected_states=['NONE'],
+ expected_http_code=202):
+ if self.dynamic_group_id:
+ self.assert_detach_configuration(
+ self.cluster_id, expected_states, expected_http_code)
+
+ def assert_detach_configuration(
+ self, cluster_id, expected_states, expected_http_code,
+ restart_inst=False):
+ client = self.auth_client
+ client.clusters.configuration_detach(cluster_id)
+ self.assert_client_code(client, expected_http_code)
+ self.active_config_group_id = None
+ self._assert_cluster_states(client, cluster_id, expected_states)
+ cluster = client.clusters.get(cluster_id)
+ self.assert_false(
+ hasattr(cluster, 'configuration'),
+ "Configuration group was not detached from the cluster.")
+
+ cluster_instances = self._get_cluster_instances(client, cluster_id)
+ for node in cluster_instances:
+ self.assert_false(
+ hasattr(node, 'configuration'),
+ "Configuration group was not detached from cluster node: %s"
+ % node.id)
+
+ if restart_inst:
+ self.config_requires_restart = True
+ cluster_instances = self._get_cluster_instances(client, cluster_id)
+ for node in cluster_instances:
+ self.assert_equal(
+ 'RESTART_REQUIRED', node.status,
+ "Node '%s' should be in 'RESTART_REQUIRED' state."
+ % node.id)
+
+ def run_detach_non_dynamic_configuration(
+ self, expected_states=['NONE'],
+ expected_http_code=202):
+ if self.non_dynamic_group_id:
+ self.assert_detach_configuration(
+ self.cluster_id, expected_states, expected_http_code,
+ restart_inst=True)
+
+ def run_delete_initial_configuration(self, expected_http_code=202):
+ if self.initial_group_id:
+ self.assert_group_delete(self.initial_group_id, expected_http_code)
+
+ def assert_group_delete(self, group_id, expected_http_code):
+ client = self.auth_client
+ client.configurations.delete(group_id)
+ self.assert_client_code(client, expected_http_code)
+
+ def run_delete_dynamic_configuration(self, expected_http_code=202):
+ if self.dynamic_group_id:
+ self.assert_group_delete(self.dynamic_group_id, expected_http_code)
+
+ def run_delete_non_dynamic_configuration(self, expected_http_code=202):
+ if self.non_dynamic_group_id:
+ self.assert_group_delete(self.non_dynamic_group_id,
+ expected_http_code)
+
class CassandraClusterRunner(ClusterRunner):