diff --git a/stacklight_tests/helpers/helpers.py b/stacklight_tests/helpers/helpers.py index 7777965..196afa4 100644 --- a/stacklight_tests/helpers/helpers.py +++ b/stacklight_tests/helpers/helpers.py @@ -616,7 +616,7 @@ class PluginHelper(object): version = self.nailgun_client.get_api_version() return version.get('release') - def check_pacemaker_resource(self, resource_name, role): + def check_pacemaker_resource(self, resource_name, role, is_ha=True): """Check that the pacemaker resource is started on nodes with given role. :param resource_name: the name of the pacemaker resource @@ -625,23 +625,33 @@ class PluginHelper(object): :type role: str :returns: None """ - cluster_id = self.cluster_id n_ctrls = self.fuel_web.get_nailgun_cluster_nodes_by_roles( - cluster_id, [role]) + self.cluster_id, [role]) d_ctrls = self.fuel_web.get_devops_nodes_by_nailgun_nodes(n_ctrls) pcm_nodes = ' '.join(self.fuel_web.get_pcm_nodes( d_ctrls[0].name, pure=True)['Online']) logger.info("pacemaker nodes are {0}".format(pcm_nodes)) resource_nodes = self.fuel_web.get_pacemaker_resource_location( - d_ctrls[0].name, resource_name) - for resource_node in resource_nodes: + d_ctrls[0].name, "{}".format(resource_name)) + if is_ha: + for resource_node in resource_nodes: + logger.info("Check resource [{0}] on node {1}".format( + resource_name, resource_node.name)) + config = self.fuel_web.get_pacemaker_config(resource_node.name) + asserts.assert_not_equal( + re.search( + "Clone Set: clone_{0} \[{0}\]\s+Started: \[ {1} \]". + format(resource_name, pcm_nodes), config), None, + 'Resource [{0}] is not properly configured'.format( + resource_name)) + else: + asserts.assert_true(len(resource_nodes), 1) + config = self.fuel_web.get_pacemaker_config(resource_nodes[0].name) logger.info("Check resource [{0}] on node {1}".format( - resource_name, resource_node.name)) - config = self.fuel_web.get_pacemaker_config(resource_node.name) + resource_name, resource_nodes[0].name)) asserts.assert_not_equal( - re.search( - "Clone Set: clone_{0} \[{0}\]\s+Started: \[ {1} \]".format( - resource_name, pcm_nodes), config), None, + re.search("{0}\s+\(ocf::fuel:{1}\):\s+Started".format( + resource_name, resource_name.split("_")[1]), config), None, 'Resource [{0}] is not properly configured'.format( resource_name)) diff --git a/stacklight_tests/openstack_telemetry/__init__.py b/stacklight_tests/openstack_telemetry/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stacklight_tests/openstack_telemetry/api.py b/stacklight_tests/openstack_telemetry/api.py new file mode 100644 index 0000000..38bedba --- /dev/null +++ b/stacklight_tests/openstack_telemetry/api.py @@ -0,0 +1,99 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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 fuelweb_test.helpers import checkers as fuelweb_checkers +from fuelweb_test import logger + +from stacklight_tests import base_test +from stacklight_tests.helpers import checkers +from stacklight_tests.helpers import helpers +from stacklight_tests.influxdb_grafana.api import InfluxdbPluginApi +from stacklight_tests.openstack_telemetry import plugin_settings + + +class OpenstackTelemeteryPluginApi(base_test.PluginApi): + def __init__(self): + super(OpenstackTelemeteryPluginApi, self).__init__() + + def get_plugin_settings(self): + return plugin_settings + + def prepare_plugin(self): + self.helpers.prepare_plugin(self.settings.plugin_path) + + def activate_plugin(self, options=None): + if options is None: + options = self.settings.default_options + self.helpers.activate_plugin( + self.settings.name, self.settings.version, options) + + def check_plugin_online(self): + non_ha_pcmk_resources = ['p_ceilometer-agent-central', + 'p_aodh-evaluator'] + ha_pcmk_resources = ['telemetry-collector-heka'] + controller_services = ['ceilometer-agent-notification', + 'ceilometer-api', 'aodh-api'] + compute_services = ['ceilometer-polling'] + controller_ips = [ + controller['ip'] for controller in + self.fuel_web.get_nailgun_cluster_nodes_by_roles( + self.helpers.cluster_id, ['controller'])] + compute_ips = [ + compute['ip'] for compute in + self.fuel_web.get_nailgun_cluster_nodes_by_roles( + self.helpers.cluster_id, ['compute'])] + logger.info("Check {} pacemaker resources".format( + non_ha_pcmk_resources)) + for resource in non_ha_pcmk_resources: + self.helpers.check_pacemaker_resource( + resource, "controller", is_ha=False) + logger.info("Check {} pacemaker resources".format(ha_pcmk_resources)) + for resource in ha_pcmk_resources: + self.helpers.check_pacemaker_resource(resource, "controller") + logger.info("Check {} services on {}".format( + controller_services, controller_ips)) + for ip in controller_ips: + for service in controller_services: + fuelweb_checkers.verify_service( + ip, service, ignore_count_of_proccesses=True) + logger.info( + "Check {} services on {}".format(compute_services, compute_ips)) + for ip in compute_ips: + for service in compute_services: + fuelweb_checkers.verify_service( + ip, service, ignore_count_of_proccesses=True) + logger.info("Check Ceilometer API") + keystone_access = self.helpers.os_conn.keystone_access + endpoint = keystone_access.service_catalog.url_for( + service_type='metering', service_name='ceilometer', + interface='internal') + if not endpoint: + raise helpers.NotFound("Cannot find ceilometer endpoint") + headers = { + 'X-Auth-Token': keystone_access.auth_token, + 'content-type': 'application/json' + } + checkers.check_http_get_response("{}/v2/capabilities".format(endpoint), + headers=headers) + logger.info("Check Ceilometer database in InfluxDB") + InfluxdbPluginApi().do_influxdb_query( + "show measurements", db="ceilometer") + + def uninstall_plugin(self): + return self.helpers.uninstall_plugin(self.settings.name, + self.settings.version) + + def check_uninstall_failure(self): + return self.helpers.check_plugin_cannot_be_uninstalled( + self.settings.name, self.settings.version) diff --git a/stacklight_tests/openstack_telemetry/plugin_settings.py b/stacklight_tests/openstack_telemetry/plugin_settings.py new file mode 100644 index 0000000..b1d0618 --- /dev/null +++ b/stacklight_tests/openstack_telemetry/plugin_settings.py @@ -0,0 +1,22 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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 stacklight_tests.helpers import helpers +from stacklight_tests import settings + +name = 'telemetry' +plugin_path = settings.OPENSTACK_TELEMETRY_PLUGIN_PATH +version = helpers.get_plugin_version(plugin_path) +default_options = {} +toolchain_options = default_options diff --git a/stacklight_tests/run_tests.py b/stacklight_tests/run_tests.py index f209854..3e9991e 100644 --- a/stacklight_tests/run_tests.py +++ b/stacklight_tests/run_tests.py @@ -65,6 +65,7 @@ def import_tests(): from stacklight_tests.toolchain import test_ldap_plugins # noqa from stacklight_tests.toolchain import test_network_templates # noqa from stacklight_tests.toolchain import test_neutron # noqa + from stacklight_tests.toolchain import test_openstack_telemetry # noqa from stacklight_tests.toolchain import test_post_install # noqa from stacklight_tests.toolchain import test_reduced_footprint # noqa from stacklight_tests.toolchain import test_smoke_bvt # noqa diff --git a/stacklight_tests/settings.py b/stacklight_tests/settings.py index 4283c41..0dda7dc 100644 --- a/stacklight_tests/settings.py +++ b/stacklight_tests/settings.py @@ -12,6 +12,10 @@ KAFKA_PLUGIN_PATH = os.environ.get('KAFKA_PLUGIN_PATH') # Ceilometer plugins CEILOMETER_REDIS_PLUGIN_PATH = os.environ.get('CEILOMETER_REDIS_PLUGIN_PATH') +# Openstack telemetery plugin +OPENSTACK_TELEMETRY_PLUGIN_PATH = os.environ.get( + 'OPENSTACK_TELEMETRY_PLUGIN_PATH') + # Detach plugins DETACH_DATABASE_PLUGIN_PATH = os.environ.get('DETACH_DATABASE_PLUGIN_PATH') DETACH_RABBITMQ_PLUGIN_PATH = os.environ.get('DETACH_RABBITMQ_PLUGIN_PATH') diff --git a/stacklight_tests/toolchain/api.py b/stacklight_tests/toolchain/api.py index 2349f63..e2dd69e 100644 --- a/stacklight_tests/toolchain/api.py +++ b/stacklight_tests/toolchain/api.py @@ -30,6 +30,7 @@ from stacklight_tests.influxdb_grafana import api as influx_api from stacklight_tests.lma_collector import api as collector_api from stacklight_tests.lma_infrastructure_alerting import ( api as infrastructure_alerting_api) +from stacklight_tests.openstack_telemetry import api as telemetry_api from stacklight_tests.toolchain import toolchain_settings @@ -47,6 +48,7 @@ class ToolchainApi(object): self.LMA_COLLECTOR = collector_api.LMACollectorPluginApi() self.LMA_INFRASTRUCTURE_ALERTING = ( infrastructure_alerting_api.InfraAlertingPluginApi()) + self.OPENSTACK_TELEMETRY = telemetry_api.OpenstackTelemeteryPluginApi() self._plugins = { self.ELASTICSEARCH_KIBANA, self.INFLUXDB_GRAFANA, @@ -66,6 +68,9 @@ class ToolchainApi(object): """Enable a plugin.""" self._disabled_plugins.remove(plugin) + def add_plugin(self, plugin): + self._plugins.add(plugin) + def call_plugin_method(self, plugin, f): """Call a method on a plugin but only if it's enabled.""" if plugin in self.plugins: diff --git a/stacklight_tests/toolchain/test_openstack_telemetry.py b/stacklight_tests/toolchain/test_openstack_telemetry.py new file mode 100644 index 0000000..7d245b8 --- /dev/null +++ b/stacklight_tests/toolchain/test_openstack_telemetry.py @@ -0,0 +1,63 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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 fuelweb_test.helpers.decorators import log_snapshot_after_test +from proboscis import test + +from stacklight_tests.toolchain import api + + +@test(groups=["openstack_telemetry"]) +class TestOpenstackTelemetry(api.ToolchainApi): + """Class for testing the Openstack Telemetry Plugin.""" + + @test(depends_on_groups=['prepare_slaves_5'], + groups=["deploy_openstack_telemetry", "deploy", + "openstack_telemetry", "smoke"]) + @log_snapshot_after_test + def deploy_openstack_telemetry(self): + """Deploy an environment with Openstack-Telemetry plugin + with Elasticsearch and InfluxDB backends. + + 1. Upload the Openstack-Telemetry, Elasticsearch-Kibana and + InfluxDB-Grafana plugins to the master node + 2. Install the plugins + 3. Create the cluster + 4. Add 3 nodes with controller roles + 5. Add 1 node with compute and cinder roles + 6. Add 1 node with elasticsearch_kibana and influxdb_grafana roles + 7. Deploy the cluster + 8. Check that plugins are running + 9. Run OSTF + + Duration 90m + """ + self.check_run("deploy_openstack_telemetry") + self.env.revert_snapshot("ready_with_5_slaves") + self.add_plugin(self.OPENSTACK_TELEMETRY) + self.disable_plugin(self.LMA_COLLECTOR) + self.disable_plugin(self.LMA_INFRASTRUCTURE_ALERTING) + self.prepare_plugins() + self.helpers.create_cluster(name=self.__class__.__name__) + self.activate_plugins() + roles = ["elasticsearch_kibana", "influxdb_grafana"] + self.helpers.deploy_cluster( + {'slave-01': ['controller'], + 'slave-02': ['controller'], + 'slave-03': ['controller'], + 'slave-04': ['compute', 'cinder'], + 'slave-05': roles}) + self.check_plugins_online() + self.helpers.run_ostf() + self.env.make_snapshot("deploy_openstack_telemetry", is_make=True)