From 28c7b99a72d6d8412cf8d7ce396aa6724d81e0f5 Mon Sep 17 00:00:00 2001 From: Vladimir Ushakov Date: Mon, 15 Aug 2016 12:02:45 +0300 Subject: [PATCH] Add zabbix smoke bvt tests. Add zabbix monitoring smoke bvt tests. Add zabbix plugin configuration file. Add zabbix api methods. Change-Id: I934c8350c1141636dc4c3018b720fdf40b36b79c --- openrc.default | 5 + stacklight_tests/helpers/helpers.py | 6 +- stacklight_tests/run_tests.py | 1 + stacklight_tests/settings.py | 9 ++ stacklight_tests/zabbix/__init__.py | 0 stacklight_tests/zabbix/api.py | 142 +++++++++++++++++++++ stacklight_tests/zabbix/plugin_settings.py | 45 +++++++ stacklight_tests/zabbix/test_smoke_bvt.py | 132 +++++++++++++++++++ 8 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 stacklight_tests/zabbix/__init__.py create mode 100644 stacklight_tests/zabbix/api.py create mode 100644 stacklight_tests/zabbix/plugin_settings.py create mode 100644 stacklight_tests/zabbix/test_smoke_bvt.py diff --git a/openrc.default b/openrc.default index 1198ce2..10be44e 100644 --- a/openrc.default +++ b/openrc.default @@ -16,6 +16,11 @@ export LMA_COLLECTOR_PLUGIN_PATH=$HOME/plugins/lma_collector-0.9-0.9.0-1.noarch. export LMA_INFRA_ALERTING_PLUGIN_PATH=$HOME/plugins/lma_infrastructure_alerting-0.9-0.9.0-1.noarch.rpm export ELASTICSEARCH_KIBANA_PLUGIN_PATH=$HOME/plugins/elasticsearch_kibana-0.9-0.9.0-1.noarch.rpm export INFLUXDB_GRAFANA_PLUGIN_PATH=$HOME/plugins/influxdb_grafana-0.9-0.9.0-1.noarch.rpm +# Zabbix plugins +export ZABBIX_MONITORING_PLUGIN_PATH=$HOME/plugins/zabbix_monitoring-2.5-2.5.1-1.noarch.rpm +export ZABBIX_MONITORING_SNMPTRAPD_PLUGIN_PATH=$HOME/plugins/zabbix_snmptrapd-1.1-1.1.0-1.noarch.rpm +export ZABBIX_MONITORING_EMC_PLUGIN_PATH=$HOME/plugins/zabbix_monitoring_emc-1.1-1.1.0-1.noarch.rpm +export ZABBIX_MONITORING_EXTREME_NETWORKS_PLUGIN_PATH=$HOME/plugins/zabbix_monitoring_extreme_networks-1.1-1.1.0-1.noarch.rpm # UI Tests settings export SELENIUM_HEADLESS=True diff --git a/stacklight_tests/helpers/helpers.py b/stacklight_tests/helpers/helpers.py index 334441c..01b83f3 100644 --- a/stacklight_tests/helpers/helpers.py +++ b/stacklight_tests/helpers/helpers.py @@ -239,7 +239,8 @@ class PluginHelper(object): return self._cluster_id def deploy_cluster(self, nodes_roles, verify_network=False, - update_interfaces=True, check_services=True): + update_interfaces=True, check_services=True, + timeout=7800): """Assign roles to nodes and deploy the cluster. :param nodes_roles: nodes to roles mapping. @@ -260,7 +261,8 @@ class PluginHelper(object): if verify_network: self.fuel_web.verify_network(self.cluster_id) self.fuel_web.deploy_cluster_wait(self.cluster_id, - check_services=check_services) + check_services=check_services, + timeout=timeout) def run_ostf(self, *args, **kwargs): """Run the OpenStack health checks.""" diff --git a/stacklight_tests/run_tests.py b/stacklight_tests/run_tests.py index 3e9991e..4ff179d 100644 --- a/stacklight_tests/run_tests.py +++ b/stacklight_tests/run_tests.py @@ -70,6 +70,7 @@ def import_tests(): from stacklight_tests.toolchain import test_reduced_footprint # noqa from stacklight_tests.toolchain import test_smoke_bvt # noqa from stacklight_tests.toolchain import test_system # noqa + from stacklight_tests.zabbix import test_smoke_bvt # noqa def run_tests(): diff --git a/stacklight_tests/settings.py b/stacklight_tests/settings.py index 0dda7dc..5c62b9e 100644 --- a/stacklight_tests/settings.py +++ b/stacklight_tests/settings.py @@ -19,3 +19,12 @@ OPENSTACK_TELEMETRY_PLUGIN_PATH = os.environ.get( # Detach plugins DETACH_DATABASE_PLUGIN_PATH = os.environ.get('DETACH_DATABASE_PLUGIN_PATH') DETACH_RABBITMQ_PLUGIN_PATH = os.environ.get('DETACH_RABBITMQ_PLUGIN_PATH') + +# Zabbix plugins +ZABBIX_MONITORING_PLUGIN_PATH = os.environ.get('ZABBIX_MONITORING_PLUGIN_PATH') +ZABBIX_MONITORING_EMC_PLUGIN_PATH = os.environ.get( + 'ZABBIX_MONITORING_EMC_PLUGIN_PATH') +ZABBIX_MONITORING_EXTREME_NETWORKS_PLUGIN_PATH = os.environ.get( + 'ZABBIX_MONITORING_EXTREME_NETWORKS_PLUGIN_PATH') +ZABBIX_MONITORING_SNMPTRAPD_PLUGIN_PATH = os.environ.get( + 'ZABBIX_MONITORING_SNMPTRAPD_PLUGIN_PATH') diff --git a/stacklight_tests/zabbix/__init__.py b/stacklight_tests/zabbix/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stacklight_tests/zabbix/api.py b/stacklight_tests/zabbix/api.py new file mode 100644 index 0000000..66c5c63 --- /dev/null +++ b/stacklight_tests/zabbix/api.py @@ -0,0 +1,142 @@ +# 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. +import bs4 +import requests +import urllib +import urlparse + +from proboscis import asserts + +from stacklight_tests.helpers import checkers +from stacklight_tests.helpers import helpers +from stacklight_tests.helpers import remote_ops + +from stacklight_tests import base_test +from stacklight_tests.zabbix import plugin_settings as zabbix_plugin_settings + + +class ZabbixWeb(object): + def __init__(self, zabbix_url, username, password, protocol, verify=False): + self.session = requests.Session() + adapter = requests.adapters.HTTPAdapter(max_retries=3) + self.session.mount('{}://'.format(protocol), adapter) + self.base_url = zabbix_url + self.username = username + self.password = password + self.verify = verify + + def zabbix_web_login(self, autologin=1, expected_code=200): + login_params = urllib.urlencode({'request': '', + 'name': self.username, + 'password': self.password, + 'autologin': autologin, + 'enter': 'Sign in'}) + url = urlparse.urljoin(self.base_url, + '?{0}'.format(login_params)) + response = self.session.post(url, verify=self.verify) + + asserts.assert_equal( + response.status_code, expected_code, + "Login to Zabbix failed: {0}".format(response.content)) + + def get_zabbix_web_screen(self, page='screens.php', + expected_code=200): + url = urlparse.urljoin(self.base_url, page) + response = self.session.get(url, verify=self.verify) + + asserts.assert_equal(response.status_code, expected_code, + "Getting Zabbix screens failed: {0}".format( + response.content)) + + return bs4.BeautifulSoup(response.content) + + +class ZabbixApi(base_test.PluginApi): + def __init__(self): + super(ZabbixApi, self).__init__() + self.settings = zabbix_plugin_settings + self.helpers = helpers.PluginHelper(self.env) + self.checkers = checkers + self.remote_ops = remote_ops + + @property + def protocol(self): + attributes = self.helpers.nailgun_client.get_cluster_attributes( + self.helpers.cluster_id) + ssl_enabled = attributes['editable']['public_ssl']['horizon']['value'] + protocol = "https" if ssl_enabled else "http" + return protocol + + def get_plugin_settings(self): + return zabbix_plugin_settings + + def prepare_plugin(self, dependat_plugins=False): + self.helpers.prepare_plugin(self.settings.plugin_path) + if dependat_plugins: + for plugin in self.settings.dependant_plugins: + self.helpers.prepare_plugin( + self.settings.dependant_plugins[plugin]["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 activate_dependant_plugin(self, plugin, options=None): + if options is None: + options = self.settings.default_options + self.helpers.activate_plugin( + plugin["name"], plugin["version"], options) + + def get_zabbix_url(self): + return "{0}://{1}/zabbix/".format(self.protocol, self.get_zabbix_vip()) + + def get_zabbix_vip(self): + return self.helpers.fuel_web.get_public_vip(self.helpers.cluster_id) + + def check_plugin_online(self): + controller = self.fuel_web.get_nailgun_cluster_nodes_by_roles( + self.helpers.cluster_id, ['controller'])[0] + with self.fuel_web.get_ssh_for_nailgun_node(controller) as remote: + remote.check_call("dpkg --get-selections | grep zabbix") + response = remote.execute("crm resource status " + "p_zabbix-server")["stdout"][0] + asserts.assert_true("p_zabbix-server is running" in response, + "p_zabbix-server resource wasn't found" + " in pacemaker:\n{0}".format(response)) + + zabbix_web = self.get_zabbix_web() + zabbix_web.zabbix_web_login() + screens_html = zabbix_web.get_zabbix_web_screen() + screens_links = screens_html.find_all('a') + asserts.assert_true(any('charts.php?graphid=' in link.get('href') + for link in screens_links), + "Zabbix screen page does not contain " + "graphs:\n{0}".format(screens_links)) + + 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) + + def get_zabbix_web(self, username='', password=''): + username = username or self.settings.zabbix_username + password = password or self.settings.zabbix_password + + return ZabbixWeb( + self.get_zabbix_url(), username, password, self.protocol) diff --git a/stacklight_tests/zabbix/plugin_settings.py b/stacklight_tests/zabbix/plugin_settings.py new file mode 100644 index 0000000..3a3a09b --- /dev/null +++ b/stacklight_tests/zabbix/plugin_settings.py @@ -0,0 +1,45 @@ +# 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 = 'zabbix_monitoring' +plugin_path = settings.ZABBIX_MONITORING_PLUGIN_PATH +version = helpers.get_plugin_version(plugin_path) +zabbix_vip = 'zbx_vip_mgmt' +dependant_plugins = { + 'ZABBIX_MONITORING_EMC': { + 'name': 'zabbix_monitoring_emc', + 'plugin_path': settings.ZABBIX_MONITORING_EMC_PLUGIN_PATH, + 'version': helpers.get_plugin_version( + settings.ZABBIX_MONITORING_EMC_PLUGIN_PATH) + }, + 'ZABBIX_MONITORING_EXTREME_NETWORKS': { + 'name': 'zabbix_monitoring_extreme_networks', + 'plugin_path': settings.ZABBIX_MONITORING_EXTREME_NETWORKS_PLUGIN_PATH, + 'version': helpers.get_plugin_version( + settings.ZABBIX_MONITORING_EXTREME_NETWORKS_PLUGIN_PATH) + }, + 'ZABBIX_SNMPTRAPD': { + 'name': 'zabbix_snmptrapd', + 'plugin_path': settings.ZABBIX_MONITORING_SNMPTRAPD_PLUGIN_PATH, + 'version': helpers.get_plugin_version( + settings.ZABBIX_MONITORING_SNMPTRAPD_PLUGIN_PATH) + } +} +default_options = {} +zabbix_username = 'admin' +zabbix_password = 'zabbix' +base_nodes = {} diff --git a/stacklight_tests/zabbix/test_smoke_bvt.py b/stacklight_tests/zabbix/test_smoke_bvt.py new file mode 100644 index 0000000..f0e8434 --- /dev/null +++ b/stacklight_tests/zabbix/test_smoke_bvt.py @@ -0,0 +1,132 @@ +# 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.zabbix import api + + +@test(groups=["plugins"]) +class TestZabbix(api.ZabbixApi): + """Class for smoke testing the zabbix plugin.""" + + @test(depends_on_groups=['prepare_slaves_3'], + groups=["install_zabbix", "install", "zabbix_monitoring", "smoke"]) + @log_snapshot_after_test + def install_zabbix(self): + """Install Zabbix plugin and check it exists + + Scenario: + 1. Upload Zabbix plugin to the master node + 2. Install the plugin + 3. Create a cluster + 4. Check that the plugin can be enabled + + Duration 20m + """ + self.env.revert_snapshot("ready_with_3_slaves") + + self.prepare_plugin() + + self.helpers.create_cluster(name=self.__class__.__name__) + + self.activate_plugin() + + @test(depends_on_groups=["prepare_slaves_5"], + groups=["deploy_zabbix_monitoring_ha", "smoke", "zabbix", ]) + @log_snapshot_after_test + def deploy_zabbix_monitoring_ha(self): + """Deploy environment with zabbix plugin + + Scenario: + 1. Upload Zabbix plugin to the master node. + 2. Install the plugin. + 3. Create a cluster. + 4. Enable the plugin. + 5. Add 3 nodes with controller role. + 6. Add 1 node with compute role. + 7. Add 1 node with cinder role. + 8. Deploy cluster. + 9. Check plugin health. + 10. Run OSTF. + + Duration 60m + """ + self.check_run('deploy_zabbix_monitoring_ha') + + self.env.revert_snapshot("ready_with_5_slaves") + + self.prepare_plugin() + + self.helpers.create_cluster(name=self.__class__.__name__) + + self.activate_plugin() + + self.helpers.deploy_cluster( + { + 'slave-01': ['controller'], + 'slave-02': ['controller'], + 'slave-03': ['controller'], + 'slave-04': ['compute'], + 'slave-05': ['cinder'] + }, timeout=10800 + ) + + self.check_plugin_online() + + self.helpers.run_ostf() + + self.env.make_snapshot("deploy_zabbix_monitoring_ha", is_make=True) + + @test(depends_on_groups=["deploy_zabbix_monitoring_ha"], + groups=["uninstall_deployed_zabbix", "uninstall", "zabbix", + "smoke"]) + @log_snapshot_after_test + def uninstall_deployed_zabbix(self): + """Uninstall Zabbix plugin with a deployed environment + + Scenario: + 1. Try to remove the plugins using the Fuel CLI + 2. Check plugins can't be uninstalled on deployed cluster. + 3. Remove the environment. + 4. Remove the plugins. + + Duration 20m + """ + self.env.revert_snapshot("deploy_zabbix_monitoring_ha") + + self.check_uninstall_failure() + + self.fuel_web.delete_env_wait(self.helpers.cluster_id) + + self.uninstall_plugin() + + @test(depends_on_groups=["prepare_slaves_3"], + groups=["uninstall_zabbix_monitoring", "uninstall", + "zabbix_monitoring", "smoke"]) + @log_snapshot_after_test + def uninstall_zabbix_monitoring(self): + """Uninstall Zabbix plugin + + Scenario: + 1. Install the plugin. + 2. Remove the plugin. + + Duration 5m + """ + self.env.revert_snapshot("ready_with_3_slaves") + + self.prepare_plugin() + + self.uninstall_plugin()