diff --git a/.zuul.yaml b/.zuul.yaml index ba85d4909..ec7fffd71 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -17,6 +17,7 @@ - openstack/monasca-ui - openstack/python-monascaclient - openstack/tempest + - openstack/monasca-tempest-plugin - job: name: monasca-tempest-python-mysql diff --git a/monasca_tempest_tests/contrib/post_test_hook.sh b/contrib/post_test_hook.sh similarity index 88% rename from monasca_tempest_tests/contrib/post_test_hook.sh rename to contrib/post_test_hook.sh index 533df9307..106b8f0dd 100755 --- a/monasca_tempest_tests/contrib/post_test_hook.sh +++ b/contrib/post_test_hook.sh @@ -91,12 +91,4 @@ sudo chown -R $USER:stack $TEMPEST_DIR load_devstack_utilities setup_monasca_api -set_tempest_conf - -(cd $TEMPEST_DIR; testr init) -(cd $TEMPEST_DIR; testr list-tests monasca_tempest_tests > monasca_tempest_tests) -(cd $TEMPEST_DIR; cat monasca_tempest_tests) -(cd $TEMPEST_DIR; cat monasca_tempest_tests | grep gate > monasca_tempest_tests_gate) -(cd $TEMPEST_DIR; testr run --subunit --load-list=monasca_tempest_tests_gate | subunit-trace --fails) - - +set_tempest_conf \ No newline at end of file diff --git a/monasca_tempest_tests/README.md b/monasca_tempest_tests/README.md deleted file mode 100644 index 528c33a16..000000000 --- a/monasca_tempest_tests/README.md +++ /dev/null @@ -1,186 +0,0 @@ -# Introduction -The Monasca Tempest Tests use the [OpenStack Tempest Plugin Interface](https://docs.openstack.org/tempest/latest/plugin.html). This README describes how to configure and run them using a variety of methods. -Currently the devstack environment is needed to run the tests. Instructions on setting up a devstack environment can be found here: https://github.com/openstack/monasca-api/devstack/README.md. - -# Configuring to run the Monasca Tempest Tests -1. Clone the OpenStack Tempest repo, and cd to it. - - ``` - git clone https://git.openstack.org/openstack/tempest.git - cd tempest - ``` -2. Create a virtualenv for running the Tempest tests and activate it. For example in the Tempest root dir - - ``` - virtualenv .venv - source .venv/bin/activate - ``` -3. Install the Tempest requirements in the virtualenv. - - ``` - pip install -r requirements.txt -r test-requirements.txt - ``` -4. Create ```etc/tempest.conf``` in the Tempest root dir by running the following command: - - ``` - oslo-config-generator --config-file tempest/cmd/config-generator.tempest.conf --output-file etc/tempest.conf - ``` - - Add the following sections to ```tempest.conf``` for testing using the devstack environment. - - ``` - [identity] - - auth_version = v3 - uri = http://127.0.0.1/identity_admin/v2.0/ - uri_v3 = http://127.0.0.1/identity_admin/v3/ - user_lockout_failure_attempts = 2 - user_locakout_duration = 5 - user_unique_last_password_count = 2 - admin_domain_scope = True - - [auth] - - use_dynamic_credentials = True - admin_project_name = admin - admin_username = admin - admin_password = secretadmin - admin_domain_name = Default - ``` - - Edit the variable values in the identity section to match your particular environment. - -5. Create ```etc/logging.conf``` in the Tempest root dir by making a copying ```logging.conf.sample```. - -6. Clone the monasca-api repo in a directory somewhere outside of the Tempest root dir. - -7. Install the monasca-api in your venv, which will also register - the Monasca Tempest Plugin as, monasca_tests. - - cd into the monasca-api root directory. Making sure that the tempest virtual env is still active, - run the following command. - - ``` - python setup.py install - ``` - -See the [OpenStack Tempest Plugin Interface](https://docs.openstack.org/tempest/latest/plugin.html), for more details on Tempest Plugins and the plugin registration process. - -# Running the Monasca Tempest Tests -The Monasca Tempest Tests can be run using a variety of methods including: -1. [Testr](https://wiki.openstack.org/wiki/Testr) -2. [Os-testr](https://docs.openstack.org/os-testr/latest/) -3. [PyCharm](https://www.jetbrains.com/pycharm/) -4. Tempest Scripts in Devstack - -## Run the tests from the CLI using testr - -[Testr](https://wiki.openstack.org/wiki/Testr) is a test runner that can be used to run the Tempest tests. - -1. Initializing testr is necessary to set up the .testrepository directory before using it for the first time. In the Tempest root dir: - - ``` - testr init - ``` - -2. Create a list of the Monasca Tempest Tests in a file: - - ``` - testr list-tests monasca_tempest_tests > monasca_tempest_tests - ``` - -3. Run the tests using testr: - - ``` - testr run --load-list=monasca_tempest_tests - ``` -You can also use testr to create a list of specific tests for your needs. - -## Run the tests using Tempest Run command - -``tempest run`` is a domain-specific command to be used as the primary -entry point for running Tempest tests. - -1. In the Tempest root dir: - - ``` - tempest run -r monasca_tempest_tests - ``` - -## Run the tests from the CLI using os-testr (no file necessary) -[Os-testr](https://docs.openstack.org/os-testr/latest/) is a test wrapper that can be used to run the Monasca Tempest tests. - -1. In the Tempest root dir: - - ``` - ostestr --serial --regex monasca_tempest_tests - ``` - ```--serial``` option is necessary here. Monasca tempest tests can't be run in parallel (default option in ostestr) because some tests depend on the same data and will randomly fail. - -## Running/Debugging the Monasca Tempest Tests in PyCharm - -You need to install `nose` for running tests from PyCharm: -``` -pip install nose -``` - -Assuming that you have already created a PyCharm project for the ```monasca-api``` do the following: - -1. In PyCharm, Edit Configurations and add a new Python tests configuration by selecting Python tests->Nosetests. -2. Name the test. For example TestVersions. -3. Set the path to the script with the tests to run. For example, ~/repos/monasca-api/monasca_tempest_tests/api/test_versions.py -4. Set the name of the Class to test. For example TestVersions. -5. Set the working directory to your local root Tempest repo. For example, ~/repos/tempest. -6. Select the Python interpreter for your project to be the same as the one virtualenv created above. For example, ~/repos/tempest/.venv -7. Run the tests. You should also be able to debug them. -8. Step and repeat for other tests. - -## Run the tests from the CLI using tempest scripts in devstack - -1. Create a virtualenv in devstack for running the tempest tests and activate it: - - ``` - cd /opt/stack/tempest - virtualenv .venv - source .venv/bin/activate - ``` -2. Install the tempest requirements in the virtualenv: - - ``` - pip install -r requirements.txt -r test-requirements.txt - ``` -3. If you want to test changes in monasca-api code on your local machine, change directory to monasca-api and install the latest monasca-api code: - - ``` - cd /vagrant_home/ - python setup.py install - ``` - Or if you want to use the current monasca api in devstack: - - ``` - cd /opt/stack/monasca-api - python setup.py install - ``` - -4. Run tempest tests: - - ``` - cd /opt/stack/tempest - testr init - ostestr --serial --regex monasca_tempest_tests - ``` - -# References -This section provides a few additional references that might be useful: -* [Tempest - The OpenStack Integration Test Suite](https://docs.openstack.org/tempest/latest/overview.html#quickstart) -* [Tempest Configuration Guide](https://github.com/openstack/tempest/blob/master/doc/source/configuration.rst#id1) -* [OpenStack Tempest Plugin Interface](https://docs.openstack.org/tempest/latest/plugin.html) - -In addition to the above references, another source of information is the following OpenStack projects: -* [Manila Tempest Tests](https://github.com/openstack/manila/tree/master/manila_tempest_tests) -* [Congress Tempest Tests](https://github.com/openstack/congress/tree/master/congress_tempest_tests). -In particular, the Manila Tempest Tests were used as a reference implementation to develop the Monasca Tempest Tests. There is also a wiki [HOWTO use tempest with manila](https://wiki.openstack.org/wiki/Manila/docs/HOWTO_use_tempest_with_manila) that might be useful for Monasca too. - -# Issues -* Update documentation for testing using Devstack when available. -* Consider changing from monasca_tempest_tests to monasca_api_tempest_tests. diff --git a/monasca_tempest_tests/__init__.py b/monasca_tempest_tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monasca_tempest_tests/clients.py b/monasca_tempest_tests/clients.py deleted file mode 100644 index a68979cfb..000000000 --- a/monasca_tempest_tests/clients.py +++ /dev/null @@ -1,23 +0,0 @@ -# (C) Copyright 2015,2017 Hewlett Packard Enterprise Development LP -# -# 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 tempest import clients - -from monasca_tempest_tests.services import monasca_client - - -class Manager(clients.Manager): - def __init__(self, credentials=None): - super(Manager, self).__init__(credentials) - self.monasca_client = monasca_client.MonascaClient(self.auth_provider) diff --git a/monasca_tempest_tests/config.py b/monasca_tempest_tests/config.py deleted file mode 100644 index 0a3a423c4..000000000 --- a/monasca_tempest_tests/config.py +++ /dev/null @@ -1,41 +0,0 @@ -# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP -# -# 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 oslo_config import cfg - - -service_option = cfg.BoolOpt("monasca", - default=True, - help="Whether or not Monasca is expected to be " - "available") - -monitoring_group = cfg.OptGroup(name="monitoring", - title="Monitoring Service Options") - -MonitoringGroup = [ - cfg.StrOpt("region", - default="", - help="The monitoring region name to use. If empty, the value " - "of identity.region is used instead. If no such region " - "is found in the service catalog, the first found one is " - "used."), - cfg.StrOpt("catalog_type", - default="monitoring", - help="Catalog type of the monitoring service."), - cfg.StrOpt('endpoint_type', - default='publicURL', - choices=['public', 'admin', 'internal', - 'publicURL', 'adminURL', 'internalURL'], - help="The endpoint type to use for the monitoring service.") -] diff --git a/monasca_tempest_tests/contrib/gate_hook.sh b/monasca_tempest_tests/contrib/gate_hook.sh deleted file mode 100755 index e69de29bb..000000000 diff --git a/monasca_tempest_tests/plugin.py b/monasca_tempest_tests/plugin.py deleted file mode 100644 index f36b82eb0..000000000 --- a/monasca_tempest_tests/plugin.py +++ /dev/null @@ -1,40 +0,0 @@ -# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP -# -# 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 os - -from tempest.test_discover import plugins - -from monasca_tempest_tests import config as config_monitoring - - -class MonascaTempestPlugin(plugins.TempestPlugin): - def load_tests(self): - base_path = os.path.split(os.path.dirname( - os.path.abspath(__file__)))[0] - test_dir = "monasca_tempest_tests/tests" - full_test_dir = os.path.join(base_path, test_dir) - return full_test_dir, base_path - - def register_opts(self, conf): - conf.register_opt(config_monitoring.service_option, - group='service_available') - conf.register_group(config_monitoring.monitoring_group) - conf.register_opts(config_monitoring.MonitoringGroup, - group='monitoring') - - def get_opt_lists(self): - return [(config_monitoring.monitoring_group.name, - config_monitoring.MonitoringGroup), - ('service_available', [config_monitoring.service_option])] diff --git a/monasca_tempest_tests/services/__init__.py b/monasca_tempest_tests/services/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monasca_tempest_tests/services/monasca_client.py b/monasca_tempest_tests/services/monasca_client.py deleted file mode 100644 index 366f5cbe0..000000000 --- a/monasca_tempest_tests/services/monasca_client.py +++ /dev/null @@ -1,346 +0,0 @@ -# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP -# -# 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 oslo_serialization import jsonutils as json - -from tempest import config -from tempest.lib.common import rest_client - -CONF = config.CONF - - -class MonascaClient(rest_client.RestClient): - - def __init__(self, auth_provider): - super(MonascaClient, self).__init__( - auth_provider, - CONF.monitoring.catalog_type, - CONF.monitoring.region or CONF.identity.region, - endpoint_type=CONF.monitoring.endpoint_type) - - def get_version(self): - resp, response_body = self.get('') - return resp, response_body - - def create_metrics(self, metrics, tenant_id=None): - uri = 'metrics' - if tenant_id: - uri = uri + '?tenant_id=%s' % tenant_id - request_body = json.dumps(metrics) - resp, response_body = self.post(uri, request_body) - return resp, response_body - - def list_metrics(self, query_params=None): - uri = 'metrics' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_metrics_names(self, query_params=None): - uri = 'metrics/names' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_dimension_names(self, query_params=None): - uri = 'metrics/dimensions/names' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_dimension_values(self, query_params=None): - uri = 'metrics/dimensions/names/values' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_measurements(self, query_params=None): - uri = 'metrics/measurements' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_statistics(self, query_params=None): - uri = 'metrics/statistics' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def create_notifications(self, notification): - uri = 'notification-methods' - request_body = json.dumps(notification) - resp, response_body = self.post(uri, request_body) - return resp, json.loads(response_body) - - def create_notification_method(self, - name=None, - type=None, - address=None, - period=None): - uri = 'notification-methods' - request_body = {} - if name is not None: - request_body['name'] = name - if type is not None: - request_body['type'] = type - if address is not None: - request_body['address'] = address - if period is not None: - request_body['period'] = period - resp, response_body = self.post(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def delete_notification_method(self, id): - uri = 'notification-methods/' + id - resp, response_body = self.delete(uri) - return resp, response_body - - def get_notification_method(self, id): - uri = 'notification-methods/' + id - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_notification_methods(self, query_params=None): - uri = 'notification-methods' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def update_notification_method(self, id, name, type, address, period=None): - uri = 'notification-methods/' + id - request_body = {} - request_body['name'] = name - request_body['type'] = type - request_body['address'] = address - if period is not None: - request_body['period'] = period - resp, response_body = self.put(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def patch_notification_method(self, id, - name=None, type=None, - address=None, period=None): - uri = 'notification-methods/' + id - request_body = {} - if name is not None: - request_body['name'] = name - if type is not None: - request_body['type'] = type - if address is not None: - request_body['address'] = address - if period is not None: - request_body['period'] = period - resp, response_body = self.patch(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def list_notification_method_types(self, query_params=None): - uri = 'notification-methods/types' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def create_alarm_definitions(self, alarm_definitions): - uri = 'alarm-definitions' - request_body = json.dumps(alarm_definitions) - resp, response_body = self.post(uri, request_body) - return resp, json.loads(response_body) - - def list_alarm_definitions(self, query_params=None): - uri = 'alarm-definitions' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def get_alarm_definition(self, id): - uri = 'alarm-definitions/' + id - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def delete_alarm_definition(self, id): - uri = 'alarm-definitions/' + id - resp, response_body = self.delete(uri) - return resp, response_body - - def update_alarm_definition(self, id, name, expression, description, - actions_enabled, match_by, - severity, alarm_actions, - ok_actions, undetermined_actions, - **kwargs): - uri = 'alarm-definitions/' + id - request_body = {} - request_body['name'] = name - request_body['expression'] = expression - request_body['description'] = description - request_body['actions_enabled'] = actions_enabled - request_body['match_by'] = match_by - request_body['severity'] = severity - request_body['alarm_actions'] = alarm_actions - request_body['ok_actions'] = ok_actions - request_body['undetermined_actions'] = undetermined_actions - - for key, value in kwargs.items(): - request_body[key] = value - - resp, response_body = self.put(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def patch_alarm_definition(self, - id, - name=None, - description=None, - expression=None, - actions_enabled=None, - match_by=None, - severity=None, - alarm_actions=None, - ok_actions=None, - undetermined_actions=None, - **kwargs): - uri = 'alarm-definitions/' + id - request_body = {} - if name is not None: - request_body['name'] = name - if description is not None: - request_body['description'] = description - if expression is not None: - request_body['expression'] = expression - if actions_enabled is not None: - request_body['actions_enabled'] = actions_enabled - if match_by is not None: - request_body['match_by'] = match_by - if severity is not None: - request_body['severity'] = severity - if alarm_actions is not None: - request_body['alarm_actions'] = alarm_actions - if ok_actions is not None: - request_body['ok_actions'] = ok_actions - if undetermined_actions is not None: - request_body['undetermined_actions'] = undetermined_actions - - for key, value in kwargs.items(): - request_body[key] = value - - resp, response_body = self.patch(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def list_alarms(self, query_params=None): - uri = 'alarms' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def get_alarm(self, id): - uri = 'alarms/' + id - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def delete_alarm(self, id): - uri = 'alarms/' + id - resp, response_body = self.delete(uri) - return resp, response_body - - def update_alarm(self, id, state, lifecycle_state, link, **kwargs): - uri = 'alarms/' + id - request_body = {} - request_body['state'] = state - request_body['lifecycle_state'] = lifecycle_state - request_body['link'] = link - - for key, value in kwargs.items(): - request_body[key] = value - - resp, response_body = self.put(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def patch_alarm(self, id, state=None, lifecycle_state=None, link=None, - **kwargs): - uri = 'alarms/' + id - request_body = {} - if state is not None: - request_body['state'] = state - if lifecycle_state is not None: - request_body['lifecycle_state'] = lifecycle_state - if link is not None: - request_body['link'] = link - - for key, value in kwargs.items(): - request_body[key] = value - - resp, response_body = self.patch(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def count_alarms(self, query_params=None): - uri = 'alarms/count' - if query_params is not None: - uri += query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_alarms_state_history(self, query_params=None): - uri = 'alarms/state-history' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - def list_alarm_state_history(self, id, query_params=None): - uri = 'alarms/' + id + '/state-history' - if query_params is not None: - uri = uri + query_params - resp, response_body = self.get(uri) - return resp, json.loads(response_body) - - # For Negative Tests - def update_alarm_definition_with_no_ok_actions(self, id, name, - expression, description, - actions_enabled, match_by, - severity, alarm_actions, - undetermined_actions, - **kwargs): - uri = 'alarm-definitions/' + id - request_body = {} - request_body['name'] = name - request_body['expression'] = expression - request_body['description'] = description - request_body['actions_enabled'] = actions_enabled - request_body['match_by'] = match_by - request_body['severity'] = severity - request_body['alarm_actions'] = alarm_actions - request_body['undetermined_actions'] = undetermined_actions - - for key, value in kwargs.items(): - request_body[key] = value - - resp, response_body = self.put(uri, json.dumps(request_body)) - return resp, json.loads(response_body) - - def update_notification_method_with_no_address(self, id, name, type, - period=None): - uri = 'notification-methods/' + id - request_body = {} - request_body['name'] = name - request_body['type'] = type - if period is not None: - request_body['period'] = period - resp, response_body = self.put(uri, json.dumps(request_body)) - return resp, json.loads(response_body) diff --git a/monasca_tempest_tests/tests/__init__.py b/monasca_tempest_tests/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monasca_tempest_tests/tests/api/__init__.py b/monasca_tempest_tests/tests/api/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monasca_tempest_tests/tests/api/base.py b/monasca_tempest_tests/tests/api/base.py deleted file mode 100644 index 2cfc2007b..000000000 --- a/monasca_tempest_tests/tests/api/base.py +++ /dev/null @@ -1,97 +0,0 @@ -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 six.moves.urllib.parse as urlparse -from tempest.common import credentials_factory -from tempest import config -from tempest.lib import exceptions -import tempest.test - -from monasca_tempest_tests import clients - -CONF = config.CONF - - -class BaseMonascaTest(tempest.test.BaseTestCase): - """Base test case class for all Monasca API tests.""" - - @classmethod - def skip_checks(cls): - super(BaseMonascaTest, cls).skip_checks() - - @classmethod - def resource_setup(cls): - super(BaseMonascaTest, cls).resource_setup() - auth_version = CONF.identity.auth_version - cls.cred_provider = credentials_factory.get_credentials_provider( - cls.__name__, - force_tenant_isolation=True, - identity_version=auth_version) - credentials = cls.cred_provider.get_creds_by_roles( - ['monasca-user', 'monasca-read-only-user', 'admin']).credentials - cls.os = clients.Manager(credentials=credentials) - cls.monasca_client = cls.os.monasca_client - cls.projects_client = cls.os.projects_client - - @staticmethod - def cleanup_resources(method, list_of_ids): - for resource_id in list_of_ids: - try: - method(resource_id) - except exceptions.NotFound: - pass - - @classmethod - def resource_cleanup(cls): - super(BaseMonascaTest, cls).resource_cleanup() - resp, response_body = cls.monasca_client.list_alarm_definitions() - if resp.status == 200: - if 'elements' in response_body: - elements = response_body['elements'] - for element in elements: - id = element['id'] - cls.monasca_client.delete_alarm_definition(id) - - resp, response_body = cls.monasca_client.list_notification_methods() - if resp.status == 200: - if 'elements' in response_body: - elements = response_body['elements'] - for element in elements: - id = element['id'] - cls.monasca_client.delete_notification_method(id) - - resp, response_body = cls.monasca_client.list_alarms() - if resp.status == 200: - if 'elements' in response_body: - elements = response_body['elements'] - for element in elements: - id = element['id'] - cls.monasca_client.delete_alarm(id) - cls.cred_provider.clear_creds() - - def _get_offset(self, response_body): - next_link = None - self_link = None - for link in response_body['links']: - if link['rel'] == 'next': - next_link = link['href'] - if link['rel'] == 'self': - self_link = link['href'] - if not next_link: - query_parms = urlparse.parse_qs(urlparse.urlparse(self_link).query) - self.fail("No next link returned with query parameters: {}".format(query_parms)) - query_params = urlparse.parse_qs(urlparse.urlparse(next_link).query) - if 'offset' not in query_params: - self.fail("No offset in next link: {}".format(next_link)) - return query_params['offset'][0] diff --git a/monasca_tempest_tests/tests/api/constants.py b/monasca_tempest_tests/tests/api/constants.py deleted file mode 100644 index 2ce3f458a..000000000 --- a/monasca_tempest_tests/tests/api/constants.py +++ /dev/null @@ -1,47 +0,0 @@ -# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development Company LP -# -# 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. - -MAX_RETRIES = 60 -RETRY_WAIT_SECS = 1 -ONE_MINUTE_TIME_OUT = 60 - -ALARM_DEFINITION_CREATION_WAIT = 1 - -MAX_METRIC_NAME_LENGTH = 255 -MAX_DIMENSION_KEY_LENGTH = 255 -MAX_DIMENSION_VALUE_LENGTH = 255 -INVALID_DIMENSION_CHARS = "<>={},\"\;&" -INVALID_NAME_CHARS = INVALID_DIMENSION_CHARS + "()" - -MAX_ALARM_DEFINITION_NAME_LENGTH = 255 -MAX_ALARM_DEFINITION_DESCRIPTION_LENGTH = 255 -MAX_ALARM_DEFINITION_ACTIONS_LENGTH = 50 - -MAX_NOTIFICATION_METHOD_NAME_LENGTH = 250 -MAX_NOTIFICATION_METHOD_TYPE_LENGTH = 100 -MAX_NOTIFICATION_METHOD_ADDRESS_LENGTH = 512 -INVALID_CHARS_NOTIFICATION = "<>={}(),\"\;&" - -MAX_LIST_MEASUREMENTS_NAME_LENGTH = 255 - -MAX_LIST_STATISTICS_NAME_LENGTH = 255 - -MAX_ALARM_LIFECYCLE_STATE_LENGTH = 50 -MAX_ALARM_METRIC_NAME_LENGTH = 255 -MAX_ALARM_METRIC_DIMENSIONS_KEY_LENGTH = 255 -MAX_ALARM_METRIC_DIMENSIONS_VALUE_LENGTH = 255 -MAX_ALARM_LINK_LENGTH = 512 - -MAX_VALUE_META_NAME_LENGTH = 255 -MAX_VALUE_META_TOTAL_LENGTH = 2048 diff --git a/monasca_tempest_tests/tests/api/helpers.py b/monasca_tempest_tests/tests/api/helpers.py deleted file mode 100644 index 0683a117d..000000000 --- a/monasca_tempest_tests/tests/api/helpers.py +++ /dev/null @@ -1,179 +0,0 @@ -# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP -# (C) Copyright SUSE LLC -# -# 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 datetime -import time - -import six.moves.urllib.parse as urlparse -from tempest.lib.common.utils import data_utils - -NUM_ALARM_DEFINITIONS = 2 -NUM_MEASUREMENTS = 100 - - -def create_metric(name='name-1', - dimensions={ - 'key-1': 'value-1', - 'key-2': 'value-2' - }, - timestamp=None, - value=0.0, - value_meta={ - 'key-1': 'value-1', - 'key-2': 'value-2' - }, - ): - metric = {} - if name is not None: - metric['name'] = name - if dimensions is not None: - metric['dimensions'] = dimensions - if timestamp is not None: - metric['timestamp'] = timestamp - else: - metric['timestamp'] = int(time.time() * 1000) - if value is not None: - metric['value'] = value - if value_meta is not None: - metric['value_meta'] = value_meta - return metric - - -def create_notification(name=data_utils.rand_name('notification-'), - type='EMAIL', - address='john.doe@domain.com', - period=0): - notification = {} - if name is not None: - notification['name'] = name - if type is not None: - notification['type'] = type - if address is not None: - notification['address'] = address - if period is not None: - notification['period'] = period - return notification - - -def create_alarm_definition(name=None, - description=None, - expression=None, - match_by=None, - severity=None, - alarm_actions=None, - ok_actions=None, - undetermined_actions=None): - alarm_definition = {} - if name is not None: - alarm_definition['name'] = name - if description is not None: - alarm_definition['description'] = description - if expression is not None: - alarm_definition['expression'] = expression - if match_by is not None: - alarm_definition['match_by'] = match_by - if severity is not None: - alarm_definition['severity'] = severity - if alarm_actions is not None: - alarm_definition['alarm_actions'] = alarm_actions - if ok_actions is not None: - alarm_definition['ok_actions'] = ok_actions - if undetermined_actions is not None: - alarm_definition['undetermined_actions'] = undetermined_actions - return alarm_definition - - -def delete_alarm_definitions(monasca_client): - # Delete alarm definitions - resp, response_body = monasca_client.list_alarm_definitions() - elements = response_body['elements'] - if elements: - for element in elements: - alarm_def_id = element['id'] - monasca_client.delete_alarm_definition(alarm_def_id) - - -def timestamp_to_iso(timestamp): - time_utc = datetime.datetime.utcfromtimestamp(timestamp / 1000.0) - time_iso_base = time_utc.strftime("%Y-%m-%dT%H:%M:%S") - time_iso_base += 'Z' - return time_iso_base - - -def timestamp_to_iso_millis(timestamp): - time_utc = datetime.datetime.utcfromtimestamp(timestamp / 1000.0) - time_iso_base = time_utc.strftime("%Y-%m-%dT%H:%M:%S") - time_iso_microsecond = time_utc.strftime(".%f") - time_iso_millisecond = time_iso_base + time_iso_microsecond[0:4] + 'Z' - return time_iso_millisecond - - -def get_query_param(uri, query_param_name): - query_param_val = None - parsed_uri = urlparse.urlparse(uri) - for query_param in parsed_uri.query.split('&'): - parsed_query_name, parsed_query_val = query_param.split('=', 1) - if query_param_name == parsed_query_name: - query_param_val = parsed_query_val - return query_param_val - - -def get_expected_elements_inner_offset_limit(all_elements, offset, limit, inner_key): - expected_elements = [] - total_statistics = 0 - - if offset is None: - offset_id = None - offset_time = "" - passed_offset = True - else: - offset_tuple = offset.split('_') - offset_id = offset_tuple[0] if len(offset_tuple) > 1 else u'0' - offset_time = offset_tuple[1] if len(offset_tuple) > 1 else offset_tuple[0] - passed_offset = False - - for element in all_elements: - element_id = element['id'] - if (not passed_offset) and element_id != offset_id: - continue - next_element = None - - for value in element[inner_key]: - if passed_offset or (element_id == offset_id and value[0] > offset_time): - if not passed_offset: - passed_offset = True - if not next_element: - next_element = element.copy() - next_element[inner_key] = [value] - else: - next_element[inner_key].append(value) - total_statistics += 1 - if total_statistics >= limit: - break - - if next_element: - expected_elements.append(next_element) - - if total_statistics >= limit: - break - - if element_id == offset_id: - passed_offset = True - - # if index is used in the element id, reset to start at zero - if expected_elements and expected_elements[0]['id'].isdigit(): - for i in range(len(expected_elements)): - expected_elements[i]['id'] = str(i) - - return expected_elements diff --git a/monasca_tempest_tests/tests/api/test_alarm_definitions.py b/monasca_tempest_tests/tests/api/test_alarm_definitions.py deleted file mode 100644 index e01b13e69..000000000 --- a/monasca_tempest_tests/tests/api/test_alarm_definitions.py +++ /dev/null @@ -1,1127 +0,0 @@ -# -*- coding: utf-8 -*- -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -import six.moves.urllib.parse as urlparse -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers - - -NUM_ALARM_DEFINITIONS = 2 - - -class TestAlarmDefinitions(base.BaseMonascaTest): - - @decorators.attr(type="gate") - def test_create_alarm_definition(self): - # Create an alarm definition - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.system_perc) > 0" - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression, - match_by=['hostname'], severity="MEDIUM") - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - self._verify_create_alarm_definitions(resp, response_body, - alarm_definition) - - @decorators.attr(type="gate") - def test_create_alarm_definition_with_notification(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - notification_address = 'root@localhost' - resp, response_body = self.monasca_client.create_notification_method( - name=notification_name, type=notification_type, - address=notification_address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, - notification_address) - - # Create an alarm definition - alarm_def_name = data_utils.rand_name('monitoring_alarm_definition') - expression = "mem_total_mb > 0" - alarm_definition = helpers.create_alarm_definition( - name=alarm_def_name, - expression=expression, - alarm_actions=[notification_id], - ok_actions=[notification_id], - undetermined_actions=[notification_id], - severity="LOW") - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - self._verify_create_alarm_definitions(resp, response_body, - alarm_definition) - self.assertEqual(notification_id, response_body['ok_actions'][0]) - self.assertEqual(notification_id, response_body['alarm_actions'][0]) - self.assertEqual(notification_id, - response_body['undetermined_actions'][0]) - - self._delete_notification(notification_id) - - @decorators.attr(type="gate") - def test_create_alarm_definition_with_multiple_notifications(self): - notification_name1 = data_utils.rand_name('notification-') - notification_type1 = 'EMAIL' - address1 = 'root@localhost' - - notification_name2 = data_utils.rand_name('notification-') - notification_type2 = 'PAGERDUTY' - address2 = 'http://localhost.com' - - resp, response_body = self.monasca_client.create_notification_method( - notification_name1, type=notification_type1, address=address1) - notification_id1 = self._verify_create_notification_method( - resp, response_body, notification_name1, notification_type1, - address1) - - resp, response_body = self.monasca_client.create_notification_method( - notification_name2, type=notification_type2, address=address2) - notification_id2 = self._verify_create_notification_method( - resp, response_body, notification_name2, notification_type2, - address2) - - # Create an alarm definition - alarm_def_name = data_utils.rand_name('monitoring_alarm_definition') - alarm_definition = helpers.create_alarm_definition( - name=alarm_def_name, - expression="mem_total_mb > 0", - alarm_actions=[notification_id1, notification_id2], - ok_actions=[notification_id1, notification_id2], - undetermined_actions=[notification_id1, notification_id2], - severity="LOW") - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - self._verify_create_alarm_definitions(resp, response_body, - alarm_definition) - - self._delete_notification(notification_id1) - self._delete_notification(notification_id2) - - @decorators.attr(type="gate") - def test_create_alarm_definition_with_url_in_expression(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - address = 'root@localhost' - resp, response_body = self.monasca_client.create_notification_method( - notification_name, type=notification_type, address=address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, address) - - # Create an alarm definition - alarm_def_name = data_utils.rand_name('monitoring_alarm_definition') - alarm_definition = helpers.create_alarm_definition( - name=alarm_def_name, - expression="avg(mem_total_mb{url=https://www.google.com}) gt 0", - alarm_actions=[notification_id], - ok_actions=[notification_id], - undetermined_actions=[notification_id], - severity="LOW") - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - self._verify_create_alarm_definitions(resp, response_body, - alarm_definition) - self._delete_notification(notification_id) - - @decorators.attr(type='gate') - def test_create_deterministic_alarm_definition(self): - name = data_utils.rand_name('log.error') - expression = "count(log.error{},deterministic) > 0" - - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - match_by=['hostname'], - severity="MEDIUM" - ) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition - ) - self._verify_create_alarm_definitions(resp, - response_body, - alarm_definition, - deterministic=True) - - @decorators.attr(type='gate') - def test_create_non_deterministic_alarm_definition_compound_mixed_expr(self): - name = data_utils.rand_name('log.error.and.disk.used_perc') - expression = ('max(disk.used_perc{hostname=node_1}) > 99.0 AND ' - 'count(log.error{hostname=node_1},deterministic) > 0') - - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - match_by=['hostname'], - severity="MEDIUM" - ) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition - ) - self._verify_create_alarm_definitions(resp, - response_body, - alarm_definition, - deterministic=False) - - @decorators.attr(type='gate') - def test_create_deterministic_alarm_definition_compound_expr(self): - name = data_utils.rand_name('log.error.nodes_1_2') - expression = ('count(log.error{hostname=node_2},deterministic) > 0 ' - 'AND ' - 'count(log.error{hostname=node_1},deterministic) > 0') - - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - match_by=['hostname'], - severity="MEDIUM" - ) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition - ) - self._verify_create_alarm_definitions(resp, - response_body, - alarm_definition, - deterministic=True) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_special_chars_in_expression(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - address = 'root@localhost' - - resp, response_body = self.monasca_client.create_notification_method( - notification_name, type=notification_type, address=address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, address) - - # Create an alarm definition - alarm_def_name = data_utils.rand_name('monitoring_alarm') - alarm_definition = helpers.create_alarm_definition( - name=alarm_def_name, - expression="avg(mem_total_mb{dev=\usr\local\bin}) " - "gt 0", - alarm_actions=[notification_id], - ok_actions=[notification_id], - undetermined_actions=[notification_id], - severity="LOW") - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_name_exceeds_max_length(self): - long_name = "x" * (constants.MAX_ALARM_DEFINITION_NAME_LENGTH + 1) - expression = "max(cpu.system_perc) > 0" - alarm_definition = helpers.create_alarm_definition( - name=long_name, description="description", expression=expression) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_description_exceeds_max_length(self): - name = data_utils.rand_name('alarm_definition') - long_description = "x" * (constants. - MAX_ALARM_DEFINITION_DESCRIPTION_LENGTH + 1) - expression = "max(cpu.system_perc) > 0" - alarm_definition = helpers.create_alarm_definition( - name=name, description=long_description, expression=expression) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_invalid_severity(self): - invalid_severity = "INVALID" - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.system_perc) > 0" - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity=invalid_severity) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_alarm_actions_exceeds_max_length( - self): - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.system_perc) > 0" - alarm_actions = ["x" * ( - constants.MAX_ALARM_DEFINITION_ACTIONS_LENGTH + 1)] - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - alarm_actions=alarm_actions) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_ok_actions_exceeds_max_length(self): - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.system_perc) > 0" - ok_actions = ["x" * (constants.MAX_ALARM_DEFINITION_ACTIONS_LENGTH + - 1)] - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - ok_actions=ok_actions) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_with_undeterm_actions_exceeds_max_length( - self): - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.system_perc) > 0" - undetermined_actions = ["x" * (constants. - MAX_ALARM_DEFINITION_ACTIONS_LENGTH + - 1)] - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - undetermined_actions=undetermined_actions) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_alarm_definitions, - alarm_definition) - - # List - - @decorators.attr(type="gate") - def test_list_alarm_definitions(self): - expression = "avg(cpu_utilization{service=compute}) >= 1234" - response_body_list = self._create_alarm_definitions( - expression=expression, number_of_definitions=1) - query_param = '?name=' + str(response_body_list[0]['name']) - resp, response_body = self.monasca_client.list_alarm_definitions( - query_param) - self._verify_list_alarm_definitions_response_body(resp, response_body) - - # Test list alarm definition response body - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, response_body_list) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_multibyte_character(self): - name = data_utils.rand_name('alarm_definition').decode('utf8') - description = 'description'.decode('utf8') - - response_body_list = self._create_alarm_definitions( - name=name, - description=description, - number_of_definitions=1 - ) - alarm_definition = response_body_list[0] - - query_param = '?name=' + urlparse.quote(name.encode('utf8')) - resp, response_body = self.monasca_client.list_alarm_definitions( - query_param) - - self._verify_list_alarm_definitions_response_body(resp, response_body) - - # Test list alarm definition response body - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, [alarm_definition]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_name(self): - name = data_utils.rand_name('alarm_definition') - alarm_definition = helpers.create_alarm_definition( - name=name, - description=data_utils.rand_name('description'), - expression="max(cpu.system_perc) > 0") - resp, res_body_create_alarm_def = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - query_parms = "?name=" + str(name) - resp, response_body = self.monasca_client.list_alarm_definitions( - query_parms) - self._verify_list_alarm_definitions_response_body(resp, response_body) - elements = response_body['elements'] - self._verify_alarm_definitions_list( - elements, [res_body_create_alarm_def]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_dimensions(self): - # Create an alarm definition with random dimensions - name = data_utils.rand_name('alarm_definition') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - expression = 'avg(cpu_utilization{' + str(key) + '=' + str(value) + \ - '}) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression) - resp, res_body_create_alarm_def = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - # List alarms - query_parms = '?dimensions=' + str(key) + ':' + str(value) - resp, response_body = self.monasca_client.\ - list_alarm_definitions(query_parms) - self._verify_list_alarm_definitions_response_body(resp, response_body) - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, [res_body_create_alarm_def]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_multiple_dimensions(self): - # Create an alarm definition with random dimensions - name = data_utils.rand_name('alarm_definition') - dimensions = {data_utils.rand_name('key-1'): data_utils.rand_name('value-1'), - data_utils.rand_name('key-2'): data_utils.rand_name('value-2')} - dimension_strings = [key + '=' + value for key, value in dimensions.items()] - expression = 'avg(cpu_utilization{' + ','.join(dimension_strings) + '}) >= 1000' - - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression) - resp, res_body_create_alarm_def = self.monasca_client. \ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - # List alarms - query_dimensions = [key + ':' + value for key, value in dimensions.items()] - query_parms = '?dimensions=' + ','.join(query_dimensions) - resp, response_body = self.monasca_client.list_alarm_definitions(query_parms) - self._verify_list_alarm_definitions_response_body(resp, response_body) - - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, [res_body_create_alarm_def]) - - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_severity(self): - name = data_utils.rand_name('alarm_definition') - expression = 'avg(cpu_utilization) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity="LOW") - resp, res_body_create_alarm_def = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - name = data_utils.rand_name('alarm_definition') - expression = 'avg(cpu_utilization) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity="MEDIUM") - resp, res_body_create_alarm_def = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - query_param = '?severity=MEDIUM' - resp, response_body = self.monasca_client.\ - list_alarm_definitions(query_param) - self._verify_list_alarm_definitions_response_body(resp, response_body) - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, [res_body_create_alarm_def]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarm_definitions_by_severity_invalid_severity(self): - query_parms = '?severity=false_severity' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarm_definitions, query_parms) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_multiple_severity(self): - name = data_utils.rand_name('alarm_definition') - expression = 'avg(cpu_utilization{alarm=severity}) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity="LOW") - resp, res_body_create_alarm_def_low = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - name = data_utils.rand_name('alarm_definition') - expression = 'avg(cpu_utilization{alarm=severity}) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity="MEDIUM") - resp, res_body_create_alarm_def_medium = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - name = data_utils.rand_name('alarm_definition') - expression = 'avg(cpu_utilization{alarm=severity}) >= 1000' - alarm_definition = helpers.create_alarm_definition( - name=name, - description="description", - expression=expression, - severity="HIGH") - resp, res_body_create_alarm_def = self.monasca_client.\ - create_alarm_definitions(alarm_definition) - self.assertEqual(201, resp.status) - - query_param = ('?severity=MEDIUM|LOW&dimensions=alarm:severity' - '&sort_by=severity') - resp, response_body = (self.monasca_client - .list_alarm_definitions(query_param)) - self._verify_list_alarm_definitions_response_body(resp, response_body) - elements = response_body['elements'] - self._verify_alarm_definitions_list(elements, [res_body_create_alarm_def_low, - res_body_create_alarm_def_medium]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarm_definitions_by_severity_multiple_values_invalid_severity(self): - query_parms = '?severity=false_severity|MEDIUM' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarm_definitions, query_parms) - - query_parms = '?severity=MEDIUM|false_severity' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarm_definitions, query_parms) - - query_parms = '?severity=LOW|false_severity|HIGH' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarm_definitions, query_parms) - - @decorators.attr(type='gate') - def test_list_alarm_definitions_sort_by(self): - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - expression = 'avg(cpu_utilization{' + str(key) + '=' + str(value) + \ - '}) >= 1000' - - alarm_definitions = [helpers.create_alarm_definition( - name='alarm def sort by 01', - expression=expression, - severity='HIGH' - ), helpers.create_alarm_definition( - name='alarm def sort by 04', - expression=expression, - severity='LOW' - ), helpers.create_alarm_definition( - name='alarm def sort by 02', - expression=expression, - severity='CRITICAL' - ), helpers.create_alarm_definition( - name='alarm def sort by 03', - expression=expression, - severity='MEDIUM' - )] - for definition in alarm_definitions: - resp, response_body = self.monasca_client.create_alarm_definitions(definition) - definition['id'] = response_body['id'] - time.sleep(1) - - sort_params1 = ['id', 'name', 'severity'] - for sort_by in sort_params1: - alarmdefs_sort_by = sorted(alarm_definitions, - key=lambda d: d[sort_by]) - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarmdefs_sort_by[i][sort_by], element[sort_by]) - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by + urlparse.quote(' asc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarmdefs_sort_by[i][sort_by], element[sort_by]) - - alarmdefs_sort_by_reverse = sorted(alarm_definitions, - key=lambda d: d[sort_by], - reverse=True) - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by + urlparse.quote(' desc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarmdefs_sort_by_reverse[i][sort_by], element[sort_by]) - - sort_params2 = ['created_at', 'updated_at'] - for sort_by in sort_params2: - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarm_definitions[i]['id'], element['id']) - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by + urlparse.quote(' asc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarm_definitions[i]['id'], element['id']) - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + sort_by + urlparse.quote(' desc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarm_definitions[-i - 1]['id'], element['id']) - - @decorators.attr(type='gate') - def test_list_alarm_definitions_multiple_sort_by(self): - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - expression = 'avg(cpu_utilization{' + str(key) + '=' + str(value) + \ - '}) >= 1000' - - alarm_definitions = [helpers.create_alarm_definition( - name='alarm def sort by 11', - expression=expression, - severity='MEDIUM' - ), helpers.create_alarm_definition( - name='alarm def sort by 14', - expression=expression, - severity='MEDIUM' - ), helpers.create_alarm_definition( - name='alarm def sort by 12', - expression=expression, - severity='LOW' - ), helpers.create_alarm_definition( - name='alarm def sort by 13', - expression=expression, - severity='MEDIUM' - )] - for definition in alarm_definitions: - resp, response_body = self.monasca_client.create_alarm_definitions(definition) - definition['id'] = response_body['id'] - - resp, response_body = self.monasca_client.list_alarm_definitions( - '?dimensions=' + str(key) + ':' + str(value) + - '&sort_by=' + urlparse.quote('severity asc,name desc,id')) - self.assertEqual(200, resp.status) - - expected_order = [2, 1, 3, 0] - - for i, element in enumerate(response_body['elements']): - self.assertEqual(alarm_definitions[expected_order[i]]['id'], element['id']) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_list_alarm_definitions_invalid_sort_by(self): - query_parms = '?sort_by=random' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarm_definitions, query_parms) - - @decorators.attr(type="gate") - def test_list_alarm_definitions_with_offset_limit(self): - helpers.delete_alarm_definitions(self.monasca_client) - expression = "max(cpu.system_perc) > 0" - self._create_alarm_definitions( - expression=expression, number_of_definitions=NUM_ALARM_DEFINITIONS) - resp, response_body = self.monasca_client.list_alarm_definitions() - self._verify_list_alarm_definitions_response_body(resp, response_body) - first_element = response_body['elements'][0] - last_element = response_body['elements'][1] - - query_parms = '?limit=2' - resp, response_body = self.monasca_client.list_alarm_definitions( - query_parms) - self.assertEqual(200, resp.status) - - elements = response_body['elements'] - self.assertEqual(2, len(elements)) - self.assertEqual(first_element, elements[0]) - self.assertEqual(last_element, elements[1]) - - for offset in range(0, 2): - for limit in range(1, 3 - offset): - query_parms = '?offset=' + str(offset) + '&limit=' + str(limit) - resp, response_body = self.monasca_client.list_alarm_definitions(query_parms) - self.assertEqual(200, resp.status) - new_elements = response_body['elements'] - self.assertEqual(limit, len(new_elements)) - self.assertEqual(elements[offset], new_elements[0]) - self.assertEqual(elements[offset + limit - 1], - new_elements[-1]) - links = response_body['links'] - for link in links: - if link['rel'] == 'next': - next_offset = helpers.get_query_param(link['href'], 'offset') - next_limit = helpers.get_query_param(link['href'], 'limit') - self.assertEqual(str(offset + limit), next_offset) - self.assertEqual(str(limit), next_limit) - - # Get - - @decorators.attr(type="gate") - def test_get_alarm_definition(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - resp, response_body = self.monasca_client.get_alarm_definition( - response_body_list[0]['id']) - self.assertEqual(200, resp.status) - self._verify_element_set(response_body) - self._verify_alarm_definitions_element(response_body, - response_body_list[0]) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - def test_get_alarm_definition_with_multibyte_character(self): - # Create an alarm definition - name = data_utils.rand_name('alarm_definition').decode('utf8') - description = 'description'.decode('utf8') - response_body_list = self._create_alarm_definitions( - name=name, - description=description, - number_of_definitions=1 - ) - alarm_definition = response_body_list[0] - - resp, response_body = self.monasca_client.get_alarm_definition( - alarm_definition['id']) - - self.assertEqual(200, resp.status) - self._verify_element_set(response_body) - self._verify_alarm_definitions_element(response_body, - alarm_definition) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - # Update - - @decorators.attr(type="gate") - def test_update_alarm_definition(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - address = 'root@localhost' - - resp, response_body = self.monasca_client.create_notification_method( - notification_name, type=notification_type, address=address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, address) - - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Update alarm definition - updated_name = data_utils.rand_name('updated_name') - updated_description = 'updated description' - updated_expression = "max(cpu.system_perc) < 0" - - resp, response_body = self.monasca_client.update_alarm_definition( - str(response_body_list[0]['id']), updated_name, updated_expression, - updated_description, True, response_body_list[0]['match_by'], - 'LOW', [notification_id], [notification_id], [notification_id]) - self.assertEqual(200, resp.status) - self._verify_update_patch_alarm_definition(response_body, updated_name, - updated_expression, - updated_description, None) - # Validate fields updated - resp, response_body = self.monasca_client.get_alarm_definition( - response_body_list[0]['id']) - self._verify_update_patch_alarm_definition(response_body, updated_name, - updated_expression, - updated_description, None) - links = response_body['links'] - self._verify_list_alarm_definitions_links(links) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_alarm_definition_with_a_different_match_by(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - name = response_body_list[0]['name'] - expression = response_body_list[0]['expression'] - description = response_body_list[0]['description'] - updated_match_by = ['hostname'] - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.update_alarm_definition, - response_body_list[0]['id'], name, expression, - description, 'true', updated_match_by, 'LOW', None, - None, None) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_alarm_definition_with_no_ok_actions(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - name = response_body_list[0]['name'] - expression = response_body_list[0]['expression'] - description = response_body_list[0]['description'] - updated_match_by = ['hostname'] - self.assertRaises( - exceptions.UnprocessableEntity, - self.monasca_client.update_alarm_definition_with_no_ok_actions, - response_body_list[0]['id'], name, expression, description, - 'true', updated_match_by, 'LOW', None, None) - - @decorators.attr(type="gate") - def test_update_notification_in_alarm_definition(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - address = 'root@localhost' - - resp, response_body = self.monasca_client.create_notification_method( - notification_name, type=notification_type, address=address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, address) - - # Create an alarm definition - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - expression = response_body_list[0]['expression'] - - # Update alarm definition - update_alarm_def_name = data_utils.rand_name('monitoring_alarm_update') - resp, response_body = self.monasca_client.update_alarm_definition( - response_body_list[0]['id'], update_alarm_def_name, expression, - 'description', True, response_body_list[0]['match_by'], 'LOW', - [notification_id], [notification_id], [notification_id]) - self.assertEqual(200, resp.status) - self._verify_update_patch_alarm_definition(response_body, - update_alarm_def_name, - None, None, notification_id) - # Get and verify details of an alarm after update - resp, response_body = self.monasca_client.get_alarm_definition( - response_body_list[0]['id']) - self._verify_update_patch_alarm_definition(response_body, - update_alarm_def_name, - None, None, notification_id) - self._delete_notification(notification_id) - - # Patch - - @decorators.attr(type="gate") - def test_patch_alarm_definition(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Patch alarm definition - patched_name = data_utils.rand_name('patched_name') - resp, response_body = self.monasca_client.patch_alarm_definition( - id=response_body_list[0]['id'], - name=patched_name - ) - self.assertEqual(200, resp.status) - self._verify_update_patch_alarm_definition(response_body, patched_name, - None, None, None) - # Validate fields updated - resp, response_body = self.monasca_client.get_alarm_definition( - response_body_list[0]['id']) - self._verify_update_patch_alarm_definition(response_body, patched_name, - None, None, None) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_alarm_definition_with_a_different_match_by(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Patch alarm definition - patched_match_by = ['hostname'] - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.patch_alarm_definition, - id=response_body_list[0]['id'], - match_by=patched_match_by) - - @decorators.attr(type="gate") - def test_patch_actions_in_alarm_definition(self): - notification_name = data_utils.rand_name('notification-') - notification_type = 'EMAIL' - address = 'root@localhost' - - resp, response_body = self.monasca_client.create_notification_method( - notification_name, type=notification_type, address=address) - notification_id = self._verify_create_notification_method( - resp, response_body, notification_name, notification_type, address) - - # Create an alarm definition - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Patch alarm definition - patch_alarm_def_name = data_utils.rand_name('monitoring_alarm_update') - resp, body = self.monasca_client.patch_alarm_definition( - response_body_list[0]['id'], - name=patch_alarm_def_name, - expression=response_body_list[0]['expression'], - actions_enabled='true', - alarm_actions=[notification_id], - ok_actions=[notification_id], - undetermined_actions=[notification_id] - ) - self.assertEqual(200, resp.status) - self._verify_update_patch_alarm_definition(body, patch_alarm_def_name, - None, None, notification_id) - # Get and verify details of an alarm after update - resp, response_body = self.monasca_client.get_alarm_definition( - response_body_list[0]['id']) - self._verify_update_patch_alarm_definition(response_body, - patch_alarm_def_name, None, - None, notification_id) - self._delete_notification(notification_id) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_alarm_definition_with_invalid_actions(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Patch alarm definition - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.patch_alarm_definition, - id=response_body_list[0]['id'], - alarm_actions=['bad_notification_id']) - - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.patch_alarm_definition, - id=response_body_list[0]['id'], - ok_actions=['bad_notification_id']) - - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.patch_alarm_definition, - id=response_body_list[0]['id'], - undetermined_actions=['bad_notification_id']) - - # Delete - - @decorators.attr(type="gate") - def test_create_and_delete_alarm_definition(self): - response_body_list = self._create_alarm_definitions( - expression=None, number_of_definitions=1) - # Delete alarm definitions - resp, response_body = self.monasca_client.list_alarm_definitions() - self._verify_list_alarm_definitions_response_body(resp, response_body) - elements = response_body['elements'] - for element in elements: - if element['id'] == response_body_list[0]['id']: - resp, body = self.monasca_client.delete_alarm_definition( - response_body_list[0]['id']) - self.assertEqual(204, resp.status) - self.assertRaises(exceptions.NotFound, - self.monasca_client.get_alarm_definition, - response_body_list[0]['id']) - return - self.fail("Failed test_create_and_delete_alarm_definition: " - "cannot find the alarm definition just created.") - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_get_alarm_defintion_with_invalid_id(self): - def_id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.get_alarm_definition, def_id) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_delete_alarm_defintion_with_invalid_id(self): - def_id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.delete_alarm_definition, def_id) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_alarm_defintion_with_invalid_id(self): - def_id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.patch_alarm_definition, - id=def_id, name='Test') - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_alarm_defintion_with_invalid_id(self): - def_id = data_utils.rand_name() - - updated_name = data_utils.rand_name('updated_name') - updated_description = 'updated description' - updated_expression = "max(cpu.system_perc) < 0" - self.assertRaises(exceptions.NotFound, - self.monasca_client.update_alarm_definition, - def_id, updated_name, updated_expression, - updated_description, True, ['device'], - 'LOW', [], [], - []) - - def _create_alarm_definitions(self, number_of_definitions, **kwargs): - self.rule = {'expression': 'mem_total_mb > 0'} - - expression = kwargs.get('expression', None) - if expression is None: - expression = 'max(cpu.system_perc) > 0' - match_by = kwargs.get('match_by', ['device']) - - response_body_list = [] - for i in range(number_of_definitions): - - name = kwargs.get('name', - data_utils.rand_name('alarm_definition')) - desc = kwargs.get('description', - data_utils.rand_name('description')) - - alarm_definition = helpers.create_alarm_definition( - name=name, - description=desc, - expression=expression, - match_by=match_by - ) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - self.assertEqual(201, resp.status) - response_body_list.append(response_body) - return response_body_list - - def _verify_list_alarm_definitions_response_body(self, resp, - response_body): - self.assertEqual(200, resp.status) - self.assertIsInstance(response_body, dict) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - - def _verify_alarm_definitions_list(self, observed, reference): - self.assertEqual(len(reference), len(observed)) - for i in range(len(reference)): - self._verify_alarm_definitions_element( - reference[i], observed[i]) - - def _verify_alarm_definitions_element(self, response_body, - res_body_create_alarm_def): - self._verify_element_set(response_body) - self.assertEqual(response_body['name'], - res_body_create_alarm_def['name']) - self.assertEqual(response_body['expression'], - res_body_create_alarm_def['expression']) - self.assertEqual(response_body['id'], res_body_create_alarm_def['id']) - self.assertEqual(response_body['description'], - res_body_create_alarm_def['description']) - self.assertEqual(response_body['match_by'], - res_body_create_alarm_def['match_by']) - self.assertEqual(response_body['severity'], - res_body_create_alarm_def['severity']) - self.assertEqual(response_body['deterministic'], - res_body_create_alarm_def['deterministic']) - - def _verify_element_set(self, element): - self.assertTrue(set(['id', - 'links', - 'name', - 'description', - 'expression', - 'deterministic', - 'match_by', - 'severity', - 'actions_enabled', - 'ok_actions', - 'alarm_actions', - 'undetermined_actions']) == - set(element)) - - def _verify_list_alarm_definitions_links(self, links): - self.assertIsInstance(links, list) - link = links[0] - self.assertTrue(set(['rel', 'href']) == set(link)) - self.assertEqual(link['rel'], u'self') - - def _verify_create_alarm_definitions(self, - resp, - response_body, - alarm_definition, - deterministic=False): - self.assertEqual(201, resp.status) - self.assertEqual(alarm_definition['name'], response_body['name']) - - self.assertEqual(alarm_definition['expression'], - str(response_body['expression'])) - self.assertEqual(deterministic, bool(response_body['deterministic'])) - - if 'description' in alarm_definition: - self.assertEqual(alarm_definition['description'], - str(response_body['description'])) - else: - self.assertEqual('', str(response_body['description'])) - if 'match_by' in alarm_definition: - self.assertEqual(alarm_definition['match_by'], - response_body['match_by']) - else: - self.assertEmpty(response_body['match_by']) - if 'severity' in alarm_definition: - self.assertEqual(alarm_definition['severity'], - str(response_body['severity'])) - else: - self.assertEqual('LOW', str(response_body['severity'])) - - def _verify_update_patch_alarm_definition(self, response_body, - updated_name, updated_expression, - updated_description, - notification_id): - if updated_name is not None: - self.assertEqual(updated_name, response_body['name']) - if updated_expression is not None: - self.assertEqual(updated_expression, response_body['expression']) - if updated_description is not None: - self.assertEqual(updated_description, response_body['description']) - if notification_id is not None: - self.assertEqual(notification_id, - response_body['alarm_actions'][0]) - self.assertEqual(notification_id, response_body['ok_actions'][0]) - self.assertEqual(notification_id, - response_body['undetermined_actions'][0]) - - def _delete_notification(self, notification_id): - resp, body = self.monasca_client.delete_notification_method( - notification_id) - self.assertEqual(204, resp.status) - - def _verify_create_notification_method( - self, resp, response_body, test_name, test_type, test_address): - self.assertEqual(201, resp.status) - self.assertEqual(test_name, response_body['name']) - self.assertEqual(test_type, response_body['type']) - self.assertEqual(test_address, response_body['address']) - notification_id = response_body['id'] - return notification_id diff --git a/monasca_tempest_tests/tests/api/test_alarm_state_history_multiple_transitions.py b/monasca_tempest_tests/tests/api/test_alarm_state_history_multiple_transitions.py deleted file mode 100644 index c58976b49..000000000 --- a/monasca_tempest_tests/tests/api/test_alarm_state_history_multiple_transitions.py +++ /dev/null @@ -1,141 +0,0 @@ -# (C) Copyright 2016-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - -MIN_HISTORY = 2 - - -class TestAlarmStateHistoryMultipleTransitions(base.BaseMonascaTest): - # For testing list alarm state history with the same alarm ID, two alarm - # transitions are needed. One transit from ALARM state to UNDETERMINED - # state and the other one from UNDETERMINED state to ALARM state. - - @classmethod - def resource_setup(cls): - super(TestAlarmStateHistoryMultipleTransitions, cls).resource_setup() - alarm_definition = helpers.create_alarm_definition( - name=data_utils.rand_name('alarm_state_history'), - expression="min(name-1) < 1.0") - cls.monasca_client.create_alarm_definitions(alarm_definition) - for timer in range(constants.MAX_RETRIES): - # create some metrics to prime the system and create - # MIN_HISTORY alarms - metric = helpers.create_metric( - name="name-1", dimensions={'key1': 'value1'}, value=0.0) - cls.monasca_client.create_metrics(metric) - # sleep 1 second between metrics to make sure timestamps - # are different in the second field. Influxdb has a bug - # where it does not sort properly by milliseconds. .014 - # is sorted as greater than .138 - time.sleep(1.0) - resp, response_body = cls.monasca_client.\ - list_alarms_state_history() - elements = response_body['elements'] - if len(elements) >= 1: - break - time.sleep(constants.RETRY_WAIT_SECS) - - time.sleep(constants.MAX_RETRIES) - - for timer in range(constants.MAX_RETRIES * 2): - metric = helpers.create_metric( - name="name-1", dimensions={'key2': 'value2'}, value=2.0) - cls.monasca_client.create_metrics(metric) - # sleep 0.05 second between metrics to make sure timestamps - # are different - time.sleep(0.05) - resp, response_body = \ - cls.monasca_client.list_alarms_state_history() - elements = response_body['elements'] - if len(elements) >= 2: - return - else: - num_transitions = len(elements) - time.sleep(constants.RETRY_WAIT_SECS) - assert False, "Required {} alarm state transitions, but found {}".\ - format(MIN_HISTORY, num_transitions) - - @classmethod - def resource_cleanup(cls): - super(TestAlarmStateHistoryMultipleTransitions, cls).\ - resource_cleanup() - - @decorators.attr(type="gate") - def test_list_alarm_state_history(self): - # Get the alarm state history for a specific alarm by ID - resp, response_body = self.monasca_client.list_alarms_state_history() - self.assertEqual(200, resp.status) - elements = response_body['elements'] - if elements: - element = elements[0] - alarm_id = element['alarm_id'] - resp, response_body = self.monasca_client.list_alarm_state_history( - alarm_id) - self.assertEqual(200, resp.status) - - # Test Response Body - self.assertTrue(set(['links', 'elements']) == - set(response_body)) - elements = response_body['elements'] - links = response_body['links'] - self.assertIsInstance(links, list) - link = links[0] - self.assertTrue(set(['rel', 'href']) == - set(link)) - self.assertEqual(link['rel'], u'self') - definition = elements[0] - self.assertTrue(set(['id', 'alarm_id', 'metrics', 'new_state', - 'old_state', 'reason', 'reason_data', - 'sub_alarms', 'timestamp']) == - set(definition)) - else: - error_msg = "Failed test_list_alarm_state_history: at least one " \ - "alarm state history is needed." - self.fail(error_msg) - - @decorators.attr(type="gate") - def test_list_alarm_state_history_with_offset_limit(self): - # Get the alarm state history for a specific alarm by ID - resp, response_body = self.monasca_client.list_alarms_state_history() - self.assertEqual(200, resp.status) - elements = response_body['elements'] - if len(elements) >= MIN_HISTORY: - element = elements[0] - second_element = elements[1] - alarm_id = element['alarm_id'] - query_parms = '?limit=1' - resp, response_body = self.monasca_client.\ - list_alarm_state_history(alarm_id, query_parms) - elements = response_body['elements'] - self.assertEqual(200, resp.status) - self.assertEqual(1, len(elements)) - - query_parms = '?offset=' + str(element['timestamp']) - resp, response_body = self.monasca_client.\ - list_alarm_state_history(alarm_id, query_parms) - elements_new = response_body['elements'] - self.assertEqual(200, resp.status) - self.assertEqual(1, len(elements_new)) - self.assertEqual(second_element, elements_new[0]) - else: - error_msg = "Failed test_list_alarm_state_history_with_offset" \ - "_limit: two alarms state history are needed." - self.fail(error_msg) diff --git a/monasca_tempest_tests/tests/api/test_alarm_transitions.py b/monasca_tempest_tests/tests/api/test_alarm_transitions.py deleted file mode 100644 index 773305bf3..000000000 --- a/monasca_tempest_tests/tests/api/test_alarm_transitions.py +++ /dev/null @@ -1,180 +0,0 @@ -# (C) Copyright 2016-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - -WAIT_SECS = 10 - - -class TestAlarmTransitions(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestAlarmTransitions, cls).resource_setup() - - @classmethod - def resource_cleanup(cls): - super(TestAlarmTransitions, cls).resource_cleanup() - - def _wait_for_alarm_creation(self, definition_id): - for x in range(WAIT_SECS): - time.sleep(1) - resp, resp_body = self.monasca_client.list_alarms( - query_params="?alarm_definition_id=" + definition_id) - - self.assertEqual(200, resp.status) - if len(resp_body['elements']) != 0: - break - self.assertEqual(1, len(resp_body['elements'])) - alarm_id = resp_body['elements'][0]['id'] - initial_state = resp_body['elements'][0]['state'] - return alarm_id, initial_state - - def _wait_for_alarm_transition(self, alarm_id, expected_state): - for x in range(WAIT_SECS): - time.sleep(1) - resp, resp_body = self.monasca_client.get_alarm(alarm_id) - self.assertEqual(200, resp.status) - if resp_body['state'] == expected_state: - break - self.assertEqual(expected_state, resp_body['state']) - - def _send_measurement(self, metric_def, value): - metric = helpers.create_metric(name=metric_def['name'], - dimensions=metric_def['dimensions'], - value=value) - resp, resp_body = self.monasca_client.create_metrics([metric]) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_alarm_max_function(self): - metric_def = { - 'name': data_utils.rand_name("max_test"), - 'dimensions': { - 'dim_to_match': data_utils.rand_name("max_match") - } - } - expression = "max(" + metric_def['name'] + ") > 14" - definition = helpers.create_alarm_definition(name="Test Max Function", - description="", - expression=expression, - match_by=["dim_to_match"]) - resp, resp_body = (self.monasca_client - .create_alarm_definitions(definition)) - self.assertEqual(201, resp.status) - definition_id = resp_body['id'] - time.sleep(1) - - self._send_measurement(metric_def, 1) - - alarm_id, initial_state = self._wait_for_alarm_creation(definition_id) - self.assertEqual("UNDETERMINED", initial_state) - - self._send_measurement(metric_def, 20) - - self._wait_for_alarm_transition(alarm_id, "ALARM") - - @decorators.attr(type="gate") - def test_alarm_max_with_deterministic(self): - metric_def = { - 'name': data_utils.rand_name("max_deterministic_test"), - 'dimensions': { - 'dim_to_match': data_utils.rand_name("max_match") - } - } - expression = "max(" + metric_def['name'] + ",deterministic) > 14" - definition = helpers.create_alarm_definition(name="Test Max Deterministic Function", - description="", - expression=expression, - match_by=["dim_to_match"]) - resp, resp_body = self.monasca_client.create_alarm_definitions(definition) - self.assertEqual(201, resp.status) - definition_id = resp_body['id'] - time.sleep(1) - - self._send_measurement(metric_def, 1) - - alarm_id, initial_state = self._wait_for_alarm_creation(definition_id) - self.assertEqual("OK", initial_state) - - self._send_measurement(metric_def, 20) - - self._wait_for_alarm_transition(alarm_id, "ALARM") - - @decorators.attr(type="gate") - def test_alarm_last_function(self): - metric_def = { - 'name': data_utils.rand_name("last_test"), - 'dimensions': { - 'dim_to_match': data_utils.rand_name("last_match") - } - } - expression = "last(" + metric_def['name'] + ") > 14" - definition = helpers.create_alarm_definition(name="Test Last Function", - description="", - expression=expression, - match_by=["dim_to_match"]) - resp, resp_body = self.monasca_client.create_alarm_definitions(definition) - self.assertEqual(201, resp.status) - definition_id = resp_body['id'] - time.sleep(1) - - self._send_measurement(metric_def, 1) - - alarm_id, initial_state = self._wait_for_alarm_creation(definition_id) - self.assertEqual("OK", initial_state) - - self._send_measurement(metric_def, 20) - - self._wait_for_alarm_transition(alarm_id, "ALARM") - - self._send_measurement(metric_def, 3) - - self._wait_for_alarm_transition(alarm_id, "OK") - - @decorators.attr(type="gate") - def test_alarm_last_with_deterministic(self): - metric_def = { - 'name': data_utils.rand_name("last_deterministic_test"), - 'dimensions': { - 'dim_to_match': data_utils.rand_name("last_match") - } - } - expression = "last(" + metric_def['name'] + ",deterministic) > 14" - definition = helpers.create_alarm_definition(name="Test Last Deterministic Function", - description="", - expression=expression, - match_by=["dim_to_match"]) - resp, resp_body = self.monasca_client.create_alarm_definitions(definition) - self.assertEqual(201, resp.status) - definition_id = resp_body['id'] - time.sleep(1) - - self._send_measurement(metric_def, 1) - - alarm_id, initial_state = self._wait_for_alarm_creation(definition_id) - self.assertEqual("OK", initial_state) - - self._send_measurement(metric_def, 20) - - self._wait_for_alarm_transition(alarm_id, "ALARM") - - self._send_measurement(metric_def, 3) - - self._wait_for_alarm_transition(alarm_id, "OK") diff --git a/monasca_tempest_tests/tests/api/test_alarms.py b/monasca_tempest_tests/tests/api/test_alarms.py deleted file mode 100644 index 6ad991e10..000000000 --- a/monasca_tempest_tests/tests/api/test_alarms.py +++ /dev/null @@ -1,1083 +0,0 @@ -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 time -import urllib - -import six.moves.urllib.parse as urlparse - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - - -class TestAlarms(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestAlarms, cls).resource_setup() - - @classmethod - def resource_cleanup(cls): - super(TestAlarms, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_list_alarms(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - resp, response_body = self.monasca_client.list_alarms() - self.assertEqual(200, resp.status) - for element in response_body['elements']: - self._verify_alarm_keys(element) - metric = element['metrics'][0] - if metric['name'] == expected_metric['name']: - self._verify_metric_in_alarm(metric, expected_metric) - return - self.fail("Failed test_list_alarms: cannot find the alarm just " - "created.") - - @decorators.attr(type="gate") - def test_list_alarms_by_alarm_definition_id(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - - @decorators.attr(type="gate") - def test_list_alarms_by_metric_name(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_parms = '?metric_name=' + expected_metric['name'] - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - self.assertEqual(alarm_definition_ids[0], element[ - 'alarm_definition']['id']) - - @decorators.attr(type="gate") - def test_list_alarms_by_metric_dimensions(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - for key in expected_metric['dimensions']: - value = expected_metric['dimensions'][key] - query_parms = '?metric_dimensions=' + key + ':' + value - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - self.assertEqual(alarm_definition_ids[0], - element['alarm_definition']['id']) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarms_by_metric_dimensions_key_exceeds_max_length(self): - key = 'x' * (constants.MAX_ALARM_METRIC_DIMENSIONS_KEY_LENGTH + 1) - query_parms = '?metric_dimensions=' + key - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarms, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarms_by_metric_dimensions_value_exceeds_max_length(self): - value = 'x' * (constants.MAX_ALARM_METRIC_DIMENSIONS_VALUE_LENGTH + 1) - query_parms = '?metric_dimensions=key:' + value - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarms, query_parms) - - @decorators.attr(type="gate") - def test_list_alarms_by_multiple_metric_dimensions(self): - metric = helpers.create_metric( - name=data_utils.rand_name("multi-dimension"), - dimensions={data_utils.rand_name("key-1"): data_utils.rand_name("value-1"), - data_utils.rand_name("key-2"): data_utils.rand_name("value-2")}, - value=20 - ) - dimension_strings = [key + '=' + value for key, value in metric['dimensions'].items()] - alarm_def = helpers.create_alarm_definition( - name=data_utils.rand_name("multi-dimensions"), - expression=metric['name'] + "{" + ','.join(dimension_strings) + '} > 15' - ) - - resp, response_body = self.monasca_client.create_alarm_definitions(alarm_def) - self.assertEqual(201, resp.status) - alarm_def_id = response_body['id'] - - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - self._wait_for_alarms(1, alarm_def_id) - - query_dimensions = [key + ':' + value for key, value in metric['dimensions'].items()] - query_parms = "?metric_dimensions=" + ','.join(query_dimensions) - - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, metric) - self.assertEqual(alarm_def_id, - element['alarm_definition']['id']) - - @decorators.attr(type="gate") - def test_list_alarms_by_metric_dimensions_no_value(self): - metric_name = data_utils.rand_name('metric') - match_by_key = data_utils.rand_name('key') - dim_key = data_utils.rand_name('key') - alarm_def = helpers.create_alarm_definition( - name=data_utils.rand_name('definition'), - expression=metric_name + " > 1", - match_by=[match_by_key]) - metric_1 = helpers.create_metric(metric_name, - {match_by_key: data_utils.rand_name('value'), - dim_key: data_utils.rand_name('value')}) - metric_2 = helpers.create_metric(metric_name, - {match_by_key: data_utils.rand_name('value'), - dim_key: data_utils.rand_name('value')}) - metric_3 = helpers.create_metric(metric_name, - {match_by_key: data_utils.rand_name('value')}) - metrics = [metric_1, metric_2, metric_3] - resp, response_body = self.monasca_client.create_alarm_definitions(alarm_def) - self.assertEqual(201, resp.status) - - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - - for i in range(constants.MAX_RETRIES): - resp, alarm_def_result = self.monasca_client.create_metrics(metrics) - self.assertEqual(204, resp.status) - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + metric_name) - self.assertEqual(200, resp.status) - if len(response_body['elements']) >= 3: - break - time.sleep(constants.RETRY_WAIT_SECS) - if i >= constants.MAX_RETRIES - 1: - self.fail("Timeout creating alarms, required 3 but found {}".format( - len(response_body['elements']))) - - query_parms = '?metric_dimensions=' + dim_key - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=2) - dimension_sets = [] - for element in response_body['elements']: - self.assertEqual(metric_name, element['metrics'][0]['name']) - dimension_sets.append(element['metrics'][0]['dimensions']) - self.assertIn(metric_1['dimensions'], dimension_sets) - self.assertIn(metric_2['dimensions'], dimension_sets) - self.assertNotIn(metric_3['dimensions'], dimension_sets) - - @decorators.attr(type="gate") - def test_list_alarms_by_metric_dimensions_multi_value(self): - metric_name = data_utils.rand_name('metric') - match_by_key = data_utils.rand_name('key') - dim_key = data_utils.rand_name('key') - dim_value_1 = data_utils.rand_name('value') - dim_value_2 = data_utils.rand_name('value') - alarm_def = helpers.create_alarm_definition( - name=data_utils.rand_name('definition'), - expression=metric_name + " > 1", - match_by=[match_by_key]) - metric_1 = helpers.create_metric(metric_name, {match_by_key: data_utils.rand_name('value'), - dim_key: dim_value_1}) - metric_2 = helpers.create_metric(metric_name, {match_by_key: data_utils.rand_name('value'), - dim_key: dim_value_2}) - metric_3 = helpers.create_metric(metric_name, {match_by_key: data_utils.rand_name('value')}) - metrics = [metric_1, metric_2, metric_3] - resp, response_body = self.monasca_client.create_alarm_definitions(alarm_def) - self.assertEqual(201, resp.status) - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - for i in range(constants.MAX_RETRIES): - resp, alarm_def_result = self.monasca_client.create_metrics(metrics) - self.assertEqual(204, resp.status) - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + metric_name) - self.assertEqual(200, resp.status) - if len(response_body['elements']) >= 3: - break - time.sleep(constants.RETRY_WAIT_SECS) - if i >= constants.MAX_RETRIES - 1: - self.fail("Timeout creating alarms, required 3 but found {}".format( - len(response_body['elements']))) - - query_parms = '?metric_dimensions=' + dim_key + ':' + dim_value_1 + '|' + dim_value_2 - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=2) - dimension_sets = [] - for element in response_body['elements']: - self.assertEqual(metric_name, element['metrics'][0]['name']) - dimension_sets.append(element['metrics'][0]['dimensions']) - self.assertIn(metric_1['dimensions'], dimension_sets) - self.assertIn(metric_2['dimensions'], dimension_sets) - self.assertNotIn(metric_3['dimensions'], dimension_sets) - - @decorators.attr(type="gate") - def test_list_alarms_by_state(self): - helpers.delete_alarm_definitions(self.monasca_client) - self._create_alarms_for_test_alarms(num=3) - resp, response_body = self.monasca_client.list_alarms() - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - elements = response_body['elements'] - len0 = len(elements) - query_parms = '?state=UNDETERMINED' - resp, response_body1 = self.monasca_client.list_alarms(query_parms) - len1 = len(response_body1['elements']) - self.assertEqual(200, resp.status) - query_parms = '?state=ok' - resp, response_body2 = self.monasca_client.list_alarms(query_parms) - len2 = len(response_body2['elements']) - self.assertEqual(200, resp.status) - query_parms = '?state=ALARM' - resp, response_body3 = self.monasca_client.list_alarms(query_parms) - len3 = len(response_body3['elements']) - self.assertEqual(200, resp.status) - self.assertEqual(len0, len1 + len2 + len3) - - @decorators.attr(type="gate") - def test_list_alarms_by_severity(self): - metric_name = data_utils.rand_name("severity-metric") - alarm_defs = [] - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='LOW' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='MEDIUM' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='HIGH' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='CRITICAL' - )) - - alarm_def_ids = [] - for definition in alarm_defs: - resp, response_body = self.monasca_client.create_alarm_definitions(definition) - self.assertEqual(201, resp.status) - alarm_def_ids.append(response_body['id']) - - # Ensure the new Alarm Definitions get to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - metric = helpers.create_metric(name=metric_name, - value=14) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - for def_id in alarm_def_ids: - self._wait_for_alarms(1, def_id) - - query_parms = '?severity=LOW' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self.assertEqual(200, resp.status) - for alarm in response_body['elements']: - self.assertEqual('LOW', alarm['alarm_definition']['severity']) - - query_parms = '?severity=HIGH' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self.assertEqual(200, resp.status) - for alarm in response_body['elements']: - self.assertEqual('HIGH', alarm['alarm_definition']['severity']) - - query_parms = '?severity=CRITICAL' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self.assertEqual(200, resp.status) - for alarm in response_body['elements']: - self.assertEqual('CRITICAL', alarm['alarm_definition']['severity']) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarms_by_severity_invalid_severity(self): - query_parms = '?severity=false_severity' - self.assertRaises(exceptions.UnprocessableEntity, self.monasca_client.list_alarms, - query_parms) - - @decorators.attr(type="gate") - def test_list_alarms_by_severity_multiple_values(self): - metric_name = data_utils.rand_name("severity-metric") - alarm_defs = [] - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='LOW' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='MEDIUM' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='HIGH' - )) - alarm_defs.append(helpers.create_alarm_definition( - name=data_utils.rand_name("alarm-severity"), - expression=metric_name + " > 12", - severity='CRITICAL' - )) - - alarm_def_ids = [] - for definition in alarm_defs: - resp, response_body = self.monasca_client.create_alarm_definitions(definition) - self.assertEqual(201, resp.status) - alarm_def_ids.append(response_body['id']) - - # Ensure the new Alarm Definitions get to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - metric = helpers.create_metric(name=metric_name, - value=14) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - for def_id in alarm_def_ids: - self._wait_for_alarms(1, def_id) - - query_parms = '?severity=LOW|MEDIUM' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self.assertEqual(200, resp.status) - for alarm in response_body['elements']: - self.assertIn(alarm['alarm_definition']['severity'], ['LOW', 'MEDIUM']) - - query_parms = '?severity=HIGH|CRITICAL' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self.assertEqual(200, resp.status) - for alarm in response_body['elements']: - self.assertIn(alarm['alarm_definition']['severity'], ['HIGH', 'CRITICAL']) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_alarms_by_severity_multiple_values_invalid_severity(self): - query_parms = '?severity=false_severity|MEDIUM' - self.assertRaises(exceptions.UnprocessableEntity, self.monasca_client.list_alarms, - query_parms) - - query_parms = '?severity=MEDIUM|false_severity' - self.assertRaises(exceptions.UnprocessableEntity, self.monasca_client.list_alarms, - query_parms) - - query_parms = '?severity=LOW|false_severity|HIGH' - self.assertRaises(exceptions.UnprocessableEntity, self.monasca_client.list_alarms, - query_parms) - - @decorators.attr(type="gate") - def test_list_alarms_by_lifecycle_state(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - alarm_id = response_body['elements'][0]['id'] - self.monasca_client.patch_alarm(id=alarm_id, lifecycle_state="OPEN") - query_parms = '?alarm_definition_id=' + str( - alarm_definition_ids[0]) + '&lifecycle_state=OPEN' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - self.assertEqual(alarm_definition_ids[0], - element['alarm_definition']['id']) - - @decorators.attr(type="gate") - def test_list_alarms_by_link(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - alarm_id = response_body['elements'][0]['id'] - self.monasca_client.patch_alarm( - id=alarm_id, link="http://somesite.com/this-alarm-info") - query_parms = '?link=http://somesite.com/this-alarm-info' - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - self.assertEqual(alarm_definition_ids[0], - element['alarm_definition']['id']) - - @decorators.attr(type="gate") - def test_list_alarms_by_state_updated_start_time(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - element = response_body['elements'][0] - state_updated_start_time = element['state_updated_timestamp'] - query_parms = '?alarm_definition_id=' + str(alarm_definition_ids[0])\ - + '&state_updated_timestamp=' + \ - str(state_updated_start_time) - resp, response_body = self.monasca_client.list_alarms(query_parms) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - first_element = response_body['elements'][0] - self.assertEqual(element, first_element) - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - self.assertEqual(alarm_definition_ids[0], - element['alarm_definition']['id']) - - @decorators.attr(type="gate") - def test_list_alarms_by_offset_limit(self): - definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=3) - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name']) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - elements = response_body['elements'] - second_element = elements[1] - offset = 1 - limit = 1 - query_parms = '?metric_name=' + expected_metric['name'] + \ - '&offset=' + str(offset) + '&limit=' + str(limit) - resp, response_body1 = self.monasca_client.list_alarms(query_parms) - elements = response_body1['elements'] - self.assertEqual(1, len(elements)) - self.assertEqual(elements[0]['id'], second_element['id']) - self.assertEqual(elements[0], second_element) - links = response_body1['links'] - next_offset = None - next_limit = None - for link in links: - if link['rel'] == 'next': - next_offset = helpers.get_query_param(link['href'], 'offset') - next_limit = helpers.get_query_param(link['href'], 'limit') - self.assertEqual(str(offset + limit), next_offset) - self.assertEqual(str(limit), next_limit) - - @decorators.attr(type="gate") - def test_get_alarm(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - element = response_body['elements'][0] - alarm_id = element['id'] - resp, response_body = self.monasca_client.get_alarm(alarm_id) - self.assertEqual(200, resp.status) - self._verify_alarm_keys(response_body) - metric = element['metrics'][0] - self._verify_metric_in_alarm(metric, expected_metric) - - @decorators.attr(type="gate") - def test_list_alarms_sort_by(self): - alarm_definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=3) - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name']) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] + - '&sort_by=created_timestamp') - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - elements = response_body['elements'] - last_timestamp = elements[0]['created_timestamp'] - for element in elements: - assert element['created_timestamp'] >= last_timestamp, \ - "Created_timestamps are not in sorted order {} came before {}".format(last_timestamp, - element['created_timestamp']) - last_timestamp = element['created_timestamp'] - - # Set link and lifecycle_state to sort in opposite order - self.monasca_client.patch_alarm(elements[0]['id'], lifecycle_state='3', link='2') - self.monasca_client.patch_alarm(elements[1]['id'], lifecycle_state='2', link='2') - self.monasca_client.patch_alarm(elements[2]['id'], lifecycle_state='4', link='1') - for iter in range(2): - sort_by_params = 'link,lifecycle_state' - if iter == 1: - query_parms = urllib.urlencode([('sort_by', sort_by_params)]) - else: - query_parms = 'sort_by=' + sort_by_params - resp, response_body = self.monasca_client.list_alarms( - '?metric_name=' + expected_metric['name'] + '&' + query_parms) - elements = response_body['elements'] - self.assertEqual(3, len(elements)) - self.assertEqual('1', elements[0]['link']) - self.assertEqual('4', elements[0]['lifecycle_state']) - self.assertEqual('2', elements[1]['link']) - self.assertEqual('2', elements[1]['lifecycle_state']) - self.assertEqual('2', elements[2]['link']) - self.assertEqual('3', elements[2]['lifecycle_state']) - - allowed_sort_by = {'alarm_id', 'alarm_definition_id', 'alarm_definition_name', - 'state', 'severity', 'lifecycle_state', 'link', - 'state_updated_timestamp', 'updated_timestamp', - 'created_timestamp'} - for sort_by in allowed_sort_by: - resp, response_body = self.monasca_client.list_alarms( - '?metric_name=' + expected_metric['name'] + '&sort_by=' + sort_by) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - elements = response_body['elements'] - last_sort_by = self._get_field_from_alarm_element(elements[0], sort_by) - for element in elements: - sort_by_field = self._get_field_from_alarm_element(element, sort_by) - assert sort_by_field >= last_sort_by, \ - "{} are not in sorted order {} came before {}".format(sort_by, - last_sort_by, - sort_by_field) - last_sort_by = sort_by_field - - @decorators.attr(type='gate') - def test_list_alarms_sort_by_asc_desc(self): - alarm_definition_ids, expected_metric = self._create_alarms_for_test_alarms(num=3) - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name']) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] + - '&sort_by=' + - urlparse.quote('created_timestamp asc')) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - elements = response_body['elements'] - last_timestamp = elements[0]['created_timestamp'] - for element in elements: - assert element['created_timestamp'] >= last_timestamp,\ - "Created_timestamps are not in ascending order {} came before {}".format(last_timestamp, - element['created_timestamp']) - last_timestamp = element['created_timestamp'] - - resp, response_body = self.monasca_client.list_alarms('?metric_name=' + expected_metric['name'] + - '&sort_by=' + - urlparse.quote('created_timestamp desc')) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - elements = response_body['elements'] - last_timestamp = elements[0]['created_timestamp'] - for element in elements: - assert element['created_timestamp'] <= last_timestamp,\ - "Created_timestamps are not in descending order {} came before {}".format(last_timestamp, - element['created_timestamp']) - last_timestamp = element['created_timestamp'] - - @decorators.attr(type="gate") - def test_list_alarms_sort_by_offset_limit(self): - metric_1 = {'name': data_utils.rand_name('sorting-metric-1'), - 'dimensions': { - data_utils.rand_name('key-1'): data_utils.rand_name('value-1')}, - 'value': 3} - metric_2 = {'name': metric_1['name'], - 'dimensions': { - data_utils.rand_name('key-2'): data_utils.rand_name('value-2')}, - 'value': 3} - alarm_def = helpers.create_alarm_definition( - name=data_utils.rand_name('sorting-def'), - expression=metric_1['name'] + " < 12", - match_by=["hostname"] - ) - resp, response_body = self.monasca_client.create_alarm_definitions(alarm_def) - self.assertEqual(201, resp.status) - alarm_def_id = response_body['id'] - - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - for i in range(3): - hostname = data_utils.rand_name('host') - metric_1['dimensions']['hostname'] = hostname - metric_2['dimensions']['hostname'] = hostname - metric_1['timestamp'] = int(time.time() * 1000) - metric_2['timestamp'] = int(time.time() * 1000) - resp, response_body = self.monasca_client.create_metrics([metric_1, metric_2]) - self.assertEqual(204, resp.status) - self._wait_for_alarms(3, alarm_def_id) - - resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id + - '&sort_by=alarm_id') - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=3) - - full_elements = response_body['elements'] - previous_id = full_elements[0]['id'] - for element in full_elements[1:]: - assert element['id'] >= previous_id, \ - "IDs are not in sorted order {} came before {}".format(previous_id, - element['id']) - previous_id = element['id'] - - resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id + - '&sort_by=alarm_id&limit=1') - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(1, len(elements)) - self.assertEqual(full_elements[0]['id'], elements[0]['id']) - - resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id + - '&sort_by=alarm_id&offset=1') - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(2, len(elements)) - self.assertEqual(full_elements[1]['id'], elements[0]['id']) - - resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id + - '&sort_by=state_updated_timestamp&offset=1') - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(2, len(elements)) - - @decorators.attr(type="gate") - def test_list_alarms_invalid_sort_by(self): - query_parms = '?sort_by=not_valid_field' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_alarms, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_get_alarm_with_invalid_id(self): - alarm_id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, self.monasca_client.get_alarm, - alarm_id) - - @decorators.attr(type="gate") - def test_update_alarm(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - element = response_body['elements'][0] - alarm_id = element['id'] - updated_state = "ALARM" - updated_lifecycle_state = "OPEN" - updated_link = "http://somesite.com" - resp, response_body = self.monasca_client.update_alarm( - id=alarm_id, state=updated_state, - lifecycle_state=updated_lifecycle_state, link=updated_link) - self.assertEqual(200, resp.status) - self._verify_alarm_keys(response_body) - # Validate fields updated - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - element = response_body['elements'][0] - self.assertEqual(updated_state, element['state']) - self.assertEqual(updated_lifecycle_state, element['lifecycle_state']) - self.assertEqual(updated_link, element['link']) - - @decorators.attr(type="gate") - def test_patch_alarm(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - alarm_id = elements[0]['id'] - patch_link = "http://somesite.com" - resp, response_body = self.monasca_client.patch_alarm( - id=alarm_id, link=patch_link) - self.assertEqual(200, resp.status) - self._verify_alarm_keys(response_body) - # Validate the field patched - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - self.assertEqual(patch_link, response_body['elements'][0]['link']) - - @decorators.attr(type="gate") - def test_delete_alarm(self): - alarm_definition_ids, expected_metric \ - = self._create_alarms_for_test_alarms(num=1) - query_param = '?alarm_definition_id=' + str(alarm_definition_ids[0]) - resp, response_body = self.monasca_client.list_alarms(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - alarm_id = elements[0]['id'] - resp, response_body = self.monasca_client.delete_alarm(alarm_id) - self.assertEqual(204, resp.status) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=0) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_delete_alarm_with_invalid_id(self): - id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.delete_alarm, id) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_alarm_with_invalid_id(self): - id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.patch_alarm, id=id, - lifecycle_state="OPEN") - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_alarm_with_invalid_id(self): - alarm_id = data_utils.rand_name() - updated_state = "ALARM" - updated_lifecycle_state = "OPEN" - updated_link = "http://somesite.com" - self.assertRaises(exceptions.NotFound, - self.monasca_client.update_alarm, - id=alarm_id, state=updated_state, - lifecycle_state=updated_lifecycle_state, - link=updated_link) - - @decorators.attr(type="gate") - def test_create_alarms_with_match_by(self): - # Create an alarm definition with no match_by - name = data_utils.rand_name('alarm_definition_1') - expression = "max(cpu.idle_perc{service=monitoring}) < 20" - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - alarm_definition_id = response_body['id'] - self._create_metrics_for_match_by( - num=1, alarm_definition_id=alarm_definition_id) - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=1) - elements = response_body['elements'] - metrics = elements[0]['metrics'] - self.assertEqual(len(metrics), 2) - self.assertNotEqual(metrics[0], metrics[1]) - - # Create an alarm definition with match_by - name = data_utils.rand_name('alarm_definition_2') - expression = "max(cpu.idle_perc{service=monitoring}) < 20" - match_by = ['hostname'] - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression, - match_by=match_by) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - alarm_definition_id = response_body['id'] - # create some metrics - self._create_metrics_for_match_by( - num=2, alarm_definition_id=alarm_definition_id) - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=2) - elements = response_body['elements'] - self.assertEqual(len(elements[0]['metrics']), 1) - self.assertEqual(len(elements[1]['metrics']), 1) - self.assertNotEqual(elements[0]['metrics'], elements[1]['metrics']) - - @decorators.attr(type="gate") - def test_create_alarms_with_sub_expressions_and_match_by(self): - # Create an alarm definition with sub-expressions and match_by - name = data_utils.rand_name('alarm_definition_3') - expression = "max(cpu.idle_perc{service=monitoring}) < 10 or " \ - "max(cpu.user_perc{service=monitoring}) > 60" - match_by = ['hostname'] - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression, - match_by=match_by) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - alarm_definition_id = response_body['id'] - self._create_metrics_for_match_by_sub_expressions( - num=2, alarm_definition_id=alarm_definition_id) - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=2) - elements = response_body['elements'] - hostnames = [] - for i in range(2): - self.assertEqual(len(elements[i]['metrics']), 2) - for i in range(2): - for j in range(2): - hostnames.append(elements[i]['metrics'][j]['dimensions'][ - 'hostname']) - self.assertEqual(hostnames[0], hostnames[1]) - self.assertEqual(hostnames[2], hostnames[3]) - self.assertNotEqual(hostnames[0], hostnames[2]) - - @decorators.attr(type="gate") - def test_create_alarms_with_match_by_list(self): - # Create an alarm definition with match_by as a list - name = data_utils.rand_name('alarm_definition') - expression = "max(cpu.idle_perc{service=monitoring}) < 10" - match_by = ['hostname', 'device'] - alarm_definition = helpers.create_alarm_definition( - name=name, description="description", expression=expression, - match_by=match_by) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - alarm_definition_id = response_body['id'] - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - # create some metrics - self._create_metrics_for_match_by_sub_expressions_list( - num=4, alarm_definition_id=alarm_definition_id) - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, - expect_num_elements=4) - elements = response_body['elements'] - dimensions = [] - for i in range(4): - self.assertEqual(len(elements[i]['metrics']), 1) - dimensions.append(elements[i]['metrics'][0]['dimensions']) - for i in range(4): - for j in range(4): - if i != j: - self.assertNotEqual(dimensions[i], dimensions[j]) - - @decorators.attr(type="gate") - def test_verify_deterministic_alarm(self): - metric_name = data_utils.rand_name('log.fancy') - metric_dimensions = {'service': 'monitoring', - 'hostname': 'mini-mon'} - - name = data_utils.rand_name('alarm_definition') - expression = ('count(%s{service=monitoring},deterministic) > 10' - % metric_name) - match_by = ['hostname', 'device'] - description = 'deterministic' - - alarm_definition = helpers.create_alarm_definition( - name=name, description=description, - expression=expression, match_by=match_by) - - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - - alarm_definition_id = response_body['id'] - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - - # 1. ensure alarm was not created - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, 0) - - # 2. put some metrics here to create it, should be in ok - metrics_count = 5 - for it in range(0, metrics_count): - metric = helpers.create_metric(name=metric_name, - value=1.0, - dimensions=metric_dimensions) - self.monasca_client.create_metrics(metric) - - self._wait_for_alarms(1, alarm_definition_id) - - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, 1) - element = response_body['elements'][0] - - self.assertEqual('OK', element['state']) - - # 3. exceed threshold - metrics_count = 20 - for it in range(0, metrics_count): - metric = helpers.create_metric(name=metric_name, - value=1.0, - dimensions=metric_dimensions) - self.monasca_client.create_metrics(metric) - - self._wait_for_alarms(1, alarm_definition_id) - - resp, response_body = self.monasca_client.list_alarms(query_param) - self._verify_list_alarms_elements(resp, response_body, 1) - element = response_body['elements'][0] - - self.assertEqual('ALARM', element['state']) - - def _verify_list_alarms_elements(self, resp, response_body, - expect_num_elements): - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == - set(response_body)) - error_msg = ("Failed: {} alarm is needed and current number " - "of alarm is {}").format(expect_num_elements, - len(response_body['elements'])) - self.assertEqual(len(response_body['elements']), - expect_num_elements, error_msg) - - def _create_alarms_for_test_alarms(self, num): - metric_name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - alarm_definition_ids = [] - for i in range(num): - # create an alarm definition - expression = "max(" + metric_name + ") > 0" - name = data_utils.rand_name('name-1') - alarm_definition = helpers.create_alarm_definition( - name=name, expression=expression) - resp, response_body = self.monasca_client.create_alarm_definitions( - alarm_definition) - alarm_definition_ids.append(response_body['id']) - expected_metric = helpers.create_metric(name=metric_name, - dimensions={key: value}) - # Ensure the new Alarm Definitions get to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - # create some metrics - for j in range(num): - for i in range(constants.MAX_RETRIES): - self.monasca_client.create_metrics(expected_metric) - time.sleep(constants.RETRY_WAIT_SECS) - query_param = '?alarm_definition_id=' + \ - str(alarm_definition_ids[j]) - resp, response_body = self.monasca_client.list_alarms( - query_param) - elements = response_body['elements'] - if len(elements) >= 1: - break - return alarm_definition_ids, expected_metric - - def _create_metrics_for_match_by(self, num, alarm_definition_id): - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - metric1 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'mini-mon'}) - metric2 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'devstack'}) - self.monasca_client.create_metrics(metric1) - self.monasca_client.create_metrics(metric2) - self._wait_for_alarms(num, alarm_definition_id) - - def _create_metrics_for_match_by_sub_expressions(self, num, - alarm_definition_id): - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - metric1 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'mini-mon'}) - metric2 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'devstack'}) - self.monasca_client.create_metrics(metric1) - self.monasca_client.create_metrics(metric2) - metric3 = helpers.create_metric( - name='cpu.user_perc', - dimensions={'service': 'monitoring', - 'hostname': 'mini-mon'}) - metric4 = helpers.create_metric( - name='cpu.user_perc', - dimensions={'service': 'monitoring', - 'hostname': 'devstack'}) - self.monasca_client.create_metrics(metric3) - self.monasca_client.create_metrics(metric4) - self._wait_for_alarms(num, alarm_definition_id) - - def _create_metrics_for_match_by_sub_expressions_list(self, num, - alarm_definition_id): - # Ensure the new Alarm Definition gets to the Threshold Engine - time.sleep(constants.ALARM_DEFINITION_CREATION_WAIT) - # create some metrics - metric1 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'mini-mon', - 'device': '/dev/sda1'}) - metric2 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'devstack', - 'device': '/dev/sda1'}) - metric3 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'mini-mon', - 'device': 'tmpfs'}) - metric4 = helpers.create_metric( - name='cpu.idle_perc', - dimensions={'service': 'monitoring', - 'hostname': 'devstack', - 'device': 'tmpfs'}) - self.monasca_client.create_metrics(metric1) - self.monasca_client.create_metrics(metric2) - self.monasca_client.create_metrics(metric3) - self.monasca_client.create_metrics(metric4) - self._wait_for_alarms(num, alarm_definition_id) - - def _wait_for_alarms(self, num, alarm_definition_id): - query_param = '?alarm_definition_id=' + str(alarm_definition_id) - for i in range(constants.MAX_RETRIES): - time.sleep(constants.RETRY_WAIT_SECS) - resp, response_body = self.monasca_client.\ - list_alarms(query_param) - elements = response_body['elements'] - if len(elements) >= num: - break - - def _verify_alarm_keys(self, response_body): - expected_keys = ['id', - 'links', - 'alarm_definition', - 'metrics', - 'state', - 'lifecycle_state', - 'link', - 'state_updated_timestamp', - 'updated_timestamp', - 'created_timestamp'] - for key in expected_keys: - self.assertIn(key, response_body) - - def _verify_metric_in_alarm(self, metric, expected_metric): - self.assertEqual(metric['dimensions'], expected_metric['dimensions']) - self.assertEqual(metric['name'], expected_metric['name']) - - def _get_field_from_alarm_element(self, element, sort_by): - if sort_by == 'alarm_id': - return element['id'] - elif sort_by == 'alarm_definition_id': - return element['alarm_definition']['id'] - elif sort_by == 'alarm_definition_name': - return element['alarm_definition']['name'] - elif sort_by == 'severity': - return element['alarm_definition']['severity'] - else: - return element[sort_by] diff --git a/monasca_tempest_tests/tests/api/test_alarms_count.py b/monasca_tempest_tests/tests/api/test_alarms_count.py deleted file mode 100644 index 94f6f30b8..000000000 --- a/monasca_tempest_tests/tests/api/test_alarms_count.py +++ /dev/null @@ -1,355 +0,0 @@ -# (C) Copyright 2016-2017 Hewlett Packard Enterprise Development LP -# -# 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 time -import urllib - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - - -GROUP_BY_ALLOWED_PARAMS = {'alarm_definition_id', 'name', 'state', 'severity', - 'link', 'lifecycle_state', 'metric_name', - 'dimension_name', 'dimension_value'} - - -class TestAlarmsCount(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestAlarmsCount, cls).resource_setup() - - num_hosts = 20 - - alarm_definitions = [] - expected_alarm_counts = [] - metrics_to_send = [] - - # OK, LOW - expression = "max(test_metric_01) > 10" - name = data_utils.rand_name('test-counts-01') - alarm_definitions.append(helpers.create_alarm_definition( - name=name, - expression=expression, - severity='LOW', - match_by=['hostname', 'unique'])) - for i in range(100): - metrics_to_send.append(helpers.create_metric( - name='test_metric_01', - dimensions={'hostname': 'test_' + str(i % num_hosts), - 'unique': str(i)}, - value=1 - )) - expected_alarm_counts.append(100) - - # ALARM, MEDIUM - expression = "max(test_metric_02) > 10" - name = data_utils.rand_name('test-counts-02') - alarm_definitions.append(helpers.create_alarm_definition( - name=name, - expression=expression, - severity='MEDIUM', - match_by=['hostname', 'unique'])) - for i in range(75): - metrics_to_send.append(helpers.create_metric( - name='test_metric_02', - dimensions={'hostname': 'test_' + str(i % num_hosts), - 'unique': str(i)}, - value=11 - )) - # append again to move from undetermined to alarm - metrics_to_send.append(helpers.create_metric( - name='test_metric_02', - dimensions={'hostname': 'test_' + str(i % num_hosts), - 'unique': str(i)}, - value=11 - )) - expected_alarm_counts.append(75) - - # OK, HIGH, shared dimension - expression = "max(test_metric_03) > 100" - name = data_utils.rand_name('test_counts-03') - alarm_definitions.append(helpers.create_alarm_definition( - name=name, - expression=expression, - severity='HIGH', - match_by=['hostname', 'unique'])) - for i in range(50): - metrics_to_send.append(helpers.create_metric( - name='test_metric_03', - dimensions={'hostname': 'test_' + str(i % num_hosts), - 'unique': str(i), - 'height': '55'}, - value=i - )) - expected_alarm_counts.append(50) - - # UNDERTERMINED, CRITICAL - expression = "max(test_metric_undet) > 100" - name = data_utils.rand_name('test-counts-04') - alarm_definitions.append(helpers.create_alarm_definition( - name=name, - expression=expression, - severity='CRITICAL', - match_by=['hostname', 'unique'])) - for i in range(25): - metrics_to_send.append(helpers.create_metric( - name='test_metric_undet', - dimensions={'hostname': 'test_' + str(i % num_hosts), - 'unique': str(i)}, - value=1 - )) - expected_alarm_counts.append(25) - - # create alarm definitions - cls.alarm_definition_ids = [] - for definition in alarm_definitions: - resp, response_body = cls.monasca_client.create_alarm_definitions( - definition) - if resp.status == 201: - cls.alarm_definition_ids.append(response_body['id']) - else: - msg = "Failed to create alarm_definition during setup: {} {}".format(resp.status, response_body) - assert False, msg - - # create alarms - for metric in metrics_to_send: - metric['timestamp'] = int(time.time() * 1000) - cls.monasca_client.create_metrics(metric) - # ensure metric timestamps are unique - time.sleep(0.01) - - # check that alarms exist - time_out = time.time() + 70 - while time.time() < time_out: - setup_complete = True - alarm_count = 0 - for i in range(len(cls.alarm_definition_ids)): - resp, response_body = cls.monasca_client.list_alarms( - '?alarm_definition_id=' + cls.alarm_definition_ids[i]) - if resp.status != 200: - msg = "Error listing alarms: {} {}".format(resp.status, response_body) - assert False, msg - if len(response_body['elements']) < expected_alarm_counts[i]: - setup_complete = False - alarm_count += len(response_body['elements']) - break - - if setup_complete: - # allow alarm transitions to occur - # time.sleep(15) - return - - msg = "Failed to create all specified alarms during setup, alarm_count was {}".format(alarm_count) - assert False, msg - - @classmethod - def resource_cleanup(cls): - super(TestAlarmsCount, cls).resource_cleanup() - - def _verify_counts_format(self, response_body, group_by=None, expected_length=None): - expected_keys = ['links', 'counts', 'columns'] - for key in expected_keys: - self.assertIn(key, response_body) - self.assertIsInstance(response_body[key], list) - - expected_columns = ['count'] - if isinstance(group_by, list): - expected_columns.extend(group_by) - self.assertEqual(expected_columns, response_body['columns']) - - if expected_length is not None: - self.assertEqual(expected_length, len(response_body['counts'])) - else: - expected_length = len(response_body['counts']) - - for i in range(expected_length): - self.assertEqual(len(expected_columns), len(response_body['counts'][i])) - - # test with no params - @decorators.attr(type='gate') - def test_count(self): - resp, response_body = self.monasca_client.count_alarms() - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body) - self.assertEqual(250, response_body['counts'][0][0]) - - # test with each group_by parameter singularly - @decorators.attr(type='gate') - def test_group_by_singular(self): - resp, response_body = self.monasca_client.list_alarms("?state=ALARM") - self.assertEqual(200, resp.status) - alarm_state_count = len(response_body['elements']) - resp, response_body = self.monasca_client.list_alarms("?state=undetermined") - self.assertEqual(200, resp.status) - undet_state_count = len(response_body['elements']) - - resp, response_body = self.monasca_client.count_alarms("?group_by=state") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, group_by=['state']) - - self.assertEqual('ALARM', response_body['counts'][0][1]) - self.assertEqual(alarm_state_count, response_body['counts'][0][0]) - self.assertEqual('UNDETERMINED', response_body['counts'][-1][1]) - self.assertEqual(undet_state_count, response_body['counts'][-1][0]) - - resp, response_body = self.monasca_client.count_alarms("?group_by=name") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, group_by=['name'], expected_length=4) - - # test with group by a parameter that is not allowed - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_group_by_not_allowed(self): - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.count_alarms, "?group_by=not_allowed") - - # test with a few group_by fields - @decorators.attr(type='gate') - def test_group_by_multiple(self): - resp, response_body = self.monasca_client.list_alarms() - alarm_low_count = 0 - for alarm in response_body['elements']: - if alarm['state'] is 'ALARM' and alarm['severity'] is 'LOW': - alarm_low_count += 1 - - # Using urlencode mimics the CLI behavior. Without the urlencode, falcon - # treats group_by as a list, with the urlencode it treats group_by as - # a string. The API needs to handle both. - # test_with_all_group_by_params tests multiple group_by without - # urlencode - query_params = urllib.urlencode([('group_by', 'state,severity')]) - resp, response_body = self.monasca_client.count_alarms("?" + query_params) - self._verify_counts_format(response_body, group_by=['state', 'severity']) - - def run_count_test(self, query_string): - resp, response_body = self.monasca_client.list_alarms(query_string) - self.assertEqual(200, resp.status) - expected_count = len(response_body['elements']) - # Make sure something was found - self.assertTrue(expected_count > 0) - - resp, response_body = self.monasca_client.count_alarms(query_string) - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, expected_length=1) - self.assertEqual(expected_count, response_body['counts'][0][0]) - - # test filter by severity - @decorators.attr(type='gate') - def test_filter_severity(self): - self.run_count_test("?severity=LOW") - - # test filter by state - @decorators.attr(type='gate') - def test_filter_state(self): - self.run_count_test("?state=ALARM") - - # test filter by metric name - @decorators.attr(type='gate') - def test_filter_metric_name(self): - self.run_count_test("?metric_name=test_metric_01") - - # test with multiple metric dimensions - @decorators.attr(type='gate') - def test_filter_multiple_dimensions(self): - self.run_count_test("?metric_dimensions=hostname:test_1,unique:1") - - # test with filter and group_by parameters - @decorators.attr(type='gate') - def test_filter_and_group_by_params(self): - resp, response_body = self.monasca_client.list_alarms("?state=ALARM") - self.assertEqual(200, resp.status) - expected_count = 0 - for element in response_body['elements']: - if element['alarm_definition']['severity'] == 'MEDIUM': - expected_count += 1 - - resp, response_body = self.monasca_client.count_alarms("?state=ALARM&group_by=severity") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, group_by=['severity']) - self.assertEqual(expected_count, response_body['counts'][0][0]) - - @decorators.attr(type='gate') - def test_with_all_group_by_params(self): - resp, response_body = self.monasca_client.list_alarms() - self.assertEqual(200, resp.status) - expected_num_count = len(response_body['elements']) - - query_params = "?group_by=" + ','.join(GROUP_BY_ALLOWED_PARAMS) - resp, response_body = self.monasca_client.count_alarms(query_params) - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, group_by=list(GROUP_BY_ALLOWED_PARAMS)) - - # Expect duplicates - msg = "Not enough distinct counts. Expected at least {}, found {}".format(expected_num_count, - len(response_body['counts'])) - assert expected_num_count <= len(response_body['counts']), msg - - @decorators.attr(type='gate') - def test_limit(self): - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value']) - assert len(response_body['counts']) > 1, "Too few counts to test limit, found 1" - - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value&limit=1") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value'], - expected_length=1) - - @decorators.attr(type='gate') - def test_offset(self): - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value']) - expected_counts = len(response_body['counts']) - 1 - - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value&offset=1") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value'], - expected_length=expected_counts) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_invalid_offset(self): - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.count_alarms, "?group_by=metric_name&offset=not_an_int") - - @decorators.attr(type='gate') - def test_limit_and_offset(self): - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value']) - expected_first_result = response_body['counts'][1] - - resp, response_body = self.monasca_client.count_alarms( - "?group_by=metric_name,dimension_name,dimension_value&offset=1&limit=5") - self.assertEqual(200, resp.status) - self._verify_counts_format(response_body, - group_by=['metric_name', 'dimension_name', 'dimension_value'], - expected_length=5) - self.assertEqual(expected_first_result, response_body['counts'][0]) diff --git a/monasca_tempest_tests/tests/api/test_alarms_state_history_one_transition.py b/monasca_tempest_tests/tests/api/test_alarms_state_history_one_transition.py deleted file mode 100644 index 33fb3b6b6..000000000 --- a/monasca_tempest_tests/tests/api/test_alarms_state_history_one_transition.py +++ /dev/null @@ -1,237 +0,0 @@ -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from oslo_utils import timeutils -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - -NUM_ALARM_DEFINITIONS = 3 -MIN_HISTORY = 3 - - -class TestAlarmsStateHistoryOneTransition(base.BaseMonascaTest): - # Alarms state histories with one transition but different alarm - # definitions are needed for this test class. - - @classmethod - def resource_setup(cls): - super(TestAlarmsStateHistoryOneTransition, cls).resource_setup() - - for i in range(MIN_HISTORY): - alarm_definition = helpers.create_alarm_definition( - name=data_utils.rand_name('alarm_state_history' + str(i + 1)), - expression="min(name-" + str(i + 1) + ") < " + str(i + 1)) - cls.monasca_client.create_alarm_definitions(alarm_definition) - - num_transitions = 0 - for timer in range(constants.MAX_RETRIES): - for i in range(MIN_HISTORY): - # Create some metrics to prime the system and waiting for the - # alarms to be created and then for them to change state. - # MIN_HISTORY number of Alarms State History are needed. - metric = helpers.create_metric(name="name-" + str(i + 1)) - cls.monasca_client.create_metrics(metric) - # Ensure alarms transition at different times - time.sleep(0.1) - resp, response_body = cls.monasca_client.\ - list_alarms_state_history() - elements = response_body['elements'] - if len(elements) >= MIN_HISTORY: - return - else: - num_transitions = len(elements) - time.sleep(constants.RETRY_WAIT_SECS) - assert False, "Required {} alarm state transitions, but found {}".\ - format(MIN_HISTORY, num_transitions) - - @classmethod - def resource_cleanup(cls): - super(TestAlarmsStateHistoryOneTransition, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_list_alarms_state_history(self): - resp, response_body = self.monasca_client.list_alarms_state_history() - self.assertEqual(200, resp.status) - # Test response body - self.assertTrue(set(['links', 'elements']) == set(response_body)) - elements = response_body['elements'] - number_of_alarms = len(elements) - if number_of_alarms < 1: - error_msg = "Failed test_list_alarms_state_history: need " \ - "at least one alarms state history to test." - self.fail(error_msg) - else: - element = elements[0] - self.assertTrue(set(['id', 'alarm_id', 'metrics', 'old_state', - 'new_state', 'reason', 'reason_data', - 'timestamp', 'sub_alarms']) - == set(element)) - - @decorators.attr(type="gate") - def test_list_alarms_state_history_with_dimensions(self): - resp, response_body = self.monasca_client.list_alarms_state_history() - elements = response_body['elements'] - if elements: - element = elements[0] - dimension = element['metrics'][0]['dimensions'] - dimension_items = dimension.items() - dimension_item = dimension_items[0] - dimension_item_0 = dimension_item[0] - dimension_item_1 = dimension_item[1] - name = element['metrics'][0]['name'] - - query_parms = '?dimensions=' + str(dimension_item_0) + ':' + str( - dimension_item_1) - resp, response_body = self.monasca_client.\ - list_alarms_state_history(query_parms) - name_new = response_body['elements'][0]['metrics'][0]['name'] - self.assertEqual(200, resp.status) - self.assertEqual(name, name_new) - else: - error_msg = "Failed test_list_alarms_state_history_with_" \ - "dimensions: need at least one alarms state history " \ - "to test." - self.fail(error_msg) - - @decorators.attr(type="gate") - def test_list_alarms_state_history_with_start_time(self): - # 1, get all histories - resp, all_response_body = self.monasca_client.\ - list_alarms_state_history() - all_elements = all_response_body['elements'] - - if len(all_elements) < 3: - error_msg = "Failed test_list_alarms_state_history_with_" \ - "start_time: need 3 or more alarms state history " \ - "to test." - self.fail(error_msg) - - # 2, query second(timestamp) <= x - min_element, second_element, max_element = \ - self._get_elements_with_min_max_timestamp(all_elements) - start_time = second_element['timestamp'] - query_params = '?start_time=' + str(start_time) - resp, selected_response_body = self.monasca_client.\ - list_alarms_state_history(query_params) - selected_elements = selected_response_body['elements'] - - # 3. compare #1 and #2 - expected_elements = all_elements - expected_elements.remove(min_element) - self.assertEqual(expected_elements, selected_elements) - - @decorators.attr(type="gate") - def test_list_alarms_state_history_with_end_time(self): - # 1, get all histories - resp, all_response_body = self.monasca_client.\ - list_alarms_state_history() - all_elements = all_response_body['elements'] - - if len(all_elements) < 3: - error_msg = "Failed test_list_alarms_state_history_with_" \ - "end_time: need 3 or more alarms state history " \ - "to test." - self.fail(error_msg) - - # 2, query x <= second(timestamp) - min_element, second_element, max_element = \ - self._get_elements_with_min_max_timestamp(all_elements) - end_time = second_element['timestamp'] - query_params = '?end_time=' + str(end_time) - resp, selected_response_body = self.monasca_client.\ - list_alarms_state_history(query_params) - selected_elements = selected_response_body['elements'] - - # 3. compare #1 and #2 - expected_elements = all_elements - expected_elements.remove(max_element) - self.assertEqual(expected_elements, selected_elements) - - @decorators.attr(type="gate") - def test_list_alarms_state_history_with_start_end_time(self): - # 1, get all histories - resp, all_response_body = self.monasca_client.\ - list_alarms_state_history() - all_elements = all_response_body['elements'] - - if len(all_elements) < 3: - error_msg = "Failed test_list_alarms_state_history_with_" \ - "start_end_time: need 3 or more alarms state history" \ - "to test." - self.fail(error_msg) - - # 2, query min(timestamp) <= x <= max(timestamp) - min_element, second_element, max_element = \ - self._get_elements_with_min_max_timestamp(all_elements) - start_time = min_element['timestamp'] - end_time = max_element['timestamp'] - query_params = '?start_time=' + str(start_time) + '&end_time=' + \ - str(end_time) - resp, selected_response_body = self.monasca_client.\ - list_alarms_state_history(query_params) - selected_elements = selected_response_body['elements'] - - # 3. compare #1 and #2 - self.assertEqual(all_elements, selected_elements) - - @decorators.attr(type="gate") - def test_list_alarms_state_history_with_offset_limit(self): - resp, response_body = self.monasca_client.list_alarms_state_history() - elements_set1 = response_body['elements'] - number_of_alarms = len(elements_set1) - if number_of_alarms >= MIN_HISTORY: - query_parms = '?limit=' + str(number_of_alarms) - resp, response_body = self.monasca_client.\ - list_alarms_state_history(query_parms) - self.assertEqual(200, resp.status) - elements_set2 = response_body['elements'] - self.assertEqual(number_of_alarms, len(elements_set2)) - for index in range(MIN_HISTORY - 1): - self.assertEqual(elements_set1[index], elements_set2[index]) - for index in range(MIN_HISTORY - 1): - alarm_history = elements_set2[index] - max_limit = len(elements_set2) - index - for limit in range(1, max_limit): - first_index = index + 1 - last_index = first_index + limit - expected_elements = elements_set2[first_index:last_index] - - query_parms = '?offset=' + str(alarm_history['timestamp'])\ - + '&limit=' + str(limit) - resp, response_body = self.\ - monasca_client.list_alarms_state_history(query_parms) - self.assertEqual(200, resp.status) - new_elements = response_body['elements'] - self.assertEqual(limit, len(new_elements)) - for i in range(len(expected_elements)): - self.assertEqual(expected_elements[i], new_elements[i]) - else: - error_msg = ("Failed test_list_alarms_state_history_with_offset " - "limit: need three alarms state history to test. " - "Current number of alarms = {}").format( - number_of_alarms) - self.fail(error_msg) - - def _get_elements_with_min_max_timestamp(self, elements): - sorted_elements = sorted(elements, key=lambda element: timeutils. - parse_isotime(element['timestamp'])) - min_element = sorted_elements[0] - second_element = sorted_elements[1] - max_element = sorted_elements[-1] - return min_element, second_element, max_element diff --git a/monasca_tempest_tests/tests/api/test_dimensions.py b/monasca_tempest_tests/tests/api/test_dimensions.py deleted file mode 100644 index 4a09e4052..000000000 --- a/monasca_tempest_tests/tests/api/test_dimensions.py +++ /dev/null @@ -1,249 +0,0 @@ -# (C) Copyright 2016 Hewlett Packard Enterprise Development LP -# (C) Copyright 2017 SUSE LLC -# -# 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 time -from urllib import urlencode - -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers - - -class TestDimensions(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestDimensions, cls).resource_setup() - metric_name1 = data_utils.rand_name() - name1 = "name_1" - name2 = "name_2" - value1 = "value_1" - value2 = "value_2" - - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - - metric1 = helpers.create_metric(name=metric_name1, - dimensions={name1: value1, - name2: value2 - }) - cls.monasca_client.create_metrics(metric1) - metric1 = helpers.create_metric(name=metric_name1, - dimensions={name1: value2}) - cls.monasca_client.create_metrics(metric1) - - metric_name2 = data_utils.rand_name() - name3 = "name_3" - value3 = "value_3" - metric2 = helpers.create_metric(name=metric_name2, - dimensions={name3: value3}) - cls.monasca_client.create_metrics(metric2) - - metric_name3 = data_utils.rand_name() - metric3 = helpers.create_metric(name=metric_name3, - dimensions={name1: value3}) - - cls.monasca_client.create_metrics(metric3) - - cls._test_metric1 = metric1 - cls._test_metric2 = metric2 - cls._test_metric_names = {metric_name1, metric_name2, metric_name3} - cls._dim_names_metric1 = [name1, name2] - cls._dim_names_metric2 = [name3] - cls._dim_names = cls._dim_names_metric1 + cls._dim_names_metric2 - cls._dim_values_for_metric1 = [value1, value2] - cls._dim_values = [value1, value2, value3] - - param = '?start_time=' + time_iso - returned_name_set = set() - for i in range(constants.MAX_RETRIES): - resp, response_body = cls.monasca_client.list_metrics( - param) - elements = response_body['elements'] - metric_name1_count = 0 - for element in elements: - returned_name_set.add(str(element['name'])) - if (str(element['name']) == metric_name1): - metric_name1_count += 1 - # Java version of influxdb never returns both metric1 in the list but Python does. - if cls._test_metric_names.issubset(returned_name_set) \ - and (metric_name1_count == 2 or i == constants.MAX_RETRIES - 1): - return - time.sleep(constants.RETRY_WAIT_SECS) - - assert False, 'Unable to initialize metrics' - - @classmethod - def resource_cleanup(cls): - super(TestDimensions, cls).resource_cleanup() - - @decorators.attr(type='gate') - def test_list_dimension_values_without_metric_name(self): - param = '?dimension_name=' + self._dim_names[0] - resp, response_body = self.monasca_client.list_dimension_values(param) - self.assertEqual(200, resp.status) - self.assertTrue({'links', 'elements'} == set(response_body)) - response_values_length = len(response_body['elements']) - values = [str(response_body['elements'][i]['dimension_value']) - for i in range(response_values_length)] - self.assertEqual(values, self._dim_values) - - @decorators.attr(type='gate') - def test_list_dimension_values_with_metric_name(self): - parms = '?metric_name=' + self._test_metric1['name'] - parms += '&dimension_name=' + self._dim_names[0] - resp, response_body = self.monasca_client.list_dimension_values(parms) - self.assertEqual(200, resp.status) - self.assertTrue({'links', 'elements'} == set(response_body)) - response_values_length = len(response_body['elements']) - values = [str(response_body['elements'][i]['dimension_value']) - for i in range(response_values_length)] - self.assertEqual(values, self._dim_values_for_metric1) - - @decorators.attr(type='gate') - def test_list_dimension_values_limit_and_offset(self): - param = '?dimension_name=' + self._dim_names[0] - resp, response_body = self.monasca_client.list_dimension_values(param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - num_dim_values = len(elements) - for limit in range(1, num_dim_values): - start_index = 0 - params = [('limit', limit)] - offset = None - while True: - num_expected_elements = limit - if (num_expected_elements + start_index) > num_dim_values: - num_expected_elements = num_dim_values - start_index - - these_params = list(params) - # If not the first call, use the offset returned by the last - # call - if offset: - these_params.extend([('offset', str(offset))]) - query_parms = '?dimension_name=' + self._dim_names[0] + '&' + \ - urlencode(these_params) - resp, response_body = \ - self.monasca_client.list_dimension_values(query_parms) - self.assertEqual(200, resp.status) - if not response_body['elements']: - self.fail("No metrics returned") - response_values_length = len(response_body['elements']) - if response_values_length == 0: - self.fail("No dimension names returned") - new_elements = [str(response_body['elements'][i] - ['dimension_value']) for i in - range(response_values_length)] - self.assertEqual(num_expected_elements, len(new_elements)) - - expected_elements = elements[start_index:start_index + limit] - expected_dimension_values = \ - [expected_elements[i]['dimension_value'] for i in range( - len(expected_elements))] - self.assertEqual(expected_dimension_values, new_elements) - start_index += num_expected_elements - if start_index >= num_dim_values: - break - # Get the next set - offset = self._get_offset(response_body) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_list_dimension_values_no_dimension_name(self): - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_dimension_values) - - @decorators.attr(type='gate') - def test_list_dimension_names(self): - resp, response_body = self.monasca_client.list_dimension_names() - self.assertEqual(200, resp.status) - self.assertTrue({'links', 'elements'} == set(response_body)) - response_names_length = len(response_body['elements']) - names = [str(response_body['elements'][i]['dimension_name']) for i - in range(response_names_length)] - self.assertEqual(names, self._dim_names) - - @decorators.attr(type='gate') - def test_list_dimension_names_with_metric_name(self): - self._test_list_dimension_names_with_metric_name( - self._test_metric1['name'], self._dim_names_metric1) - self._test_list_dimension_names_with_metric_name( - self._test_metric2['name'], self._dim_names_metric2) - - @decorators.attr(type='gate') - def test_list_dimension_names_limit_and_offset(self): - resp, response_body = self.monasca_client.list_dimension_names() - self.assertEqual(200, resp.status) - elements = response_body['elements'] - num_dim_names = len(elements) - for limit in range(1, num_dim_names): - start_index = 0 - params = [('limit', limit)] - offset = None - while True: - num_expected_elements = limit - if (num_expected_elements + start_index) > num_dim_names: - num_expected_elements = num_dim_names - start_index - - these_params = list(params) - # If not the first call, use the offset returned by the last - # call - if offset: - these_params.extend([('offset', str(offset))]) - query_parms = '?' + urlencode(these_params) - resp, response_body = self.monasca_client.list_dimension_names( - query_parms) - self.assertEqual(200, resp.status) - if not response_body['elements']: - self.fail("No metrics returned") - response_names_length = len(response_body['elements']) - if response_names_length == 0: - self.fail("No dimension names returned") - new_elements = [str(response_body['elements'][i] - ['dimension_name']) for i in - range(response_names_length)] - self.assertEqual(num_expected_elements, len(new_elements)) - - expected_elements = elements[start_index:start_index + limit] - expected_dimension_names = \ - [expected_elements[i]['dimension_name'] for i in range( - len(expected_elements))] - self.assertEqual(expected_dimension_names, new_elements) - start_index += num_expected_elements - if start_index >= num_dim_names: - break - # Get the next set - offset = self._get_offset(response_body) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_list_dimension_names_with_wrong_metric_name(self): - self._test_list_dimension_names_with_metric_name( - 'wrong_metric_name', []) - - def _test_list_dimension_names_with_metric_name(self, metric_name, - dimension_names): - param = '?metric_name=' + metric_name - resp, response_body = self.monasca_client.list_dimension_names(param) - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - response_names_length = len(response_body['elements']) - names = [str(response_body['elements'][i]['dimension_name']) for i - in range(response_names_length)] - self.assertEqual(names, dimension_names) diff --git a/monasca_tempest_tests/tests/api/test_measurements.py b/monasca_tempest_tests/tests/api/test_measurements.py deleted file mode 100644 index 49ef5e4f4..000000000 --- a/monasca_tempest_tests/tests/api/test_measurements.py +++ /dev/null @@ -1,409 +0,0 @@ -# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP -# -# 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 time - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - -NUM_MEASUREMENTS = 50 -ONE_SECOND = 1000 - - -class TestMeasurements(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestMeasurements, cls).resource_setup() - - start_timestamp = int(time.time() * 1000) - start_time = str(helpers.timestamp_to_iso(start_timestamp)) - metrics = [] - name1 = data_utils.rand_name() - name2 = data_utils.rand_name() - cls._names_list = [name1, name2] - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - cls._key = key - cls._value = value - cls._start_timestamp = start_timestamp - - for i in range(NUM_MEASUREMENTS): - metric = helpers.create_metric( - name=name1, - timestamp=start_timestamp + (i * 10), - value=i) - metrics.append(metric) - cls.monasca_client.create_metrics(metrics) - - # Create metric2 for test_list_measurements_with_dimensions - metric2 = helpers.create_metric( - name=name1, timestamp=start_timestamp + ONE_SECOND * 2, - dimensions={key: value}, value=NUM_MEASUREMENTS) - cls.monasca_client.create_metrics(metric2) - - # Create metric3 for test_list_measurements_with_offset_limit - metric3 = [ - helpers.create_metric( - name=name2, timestamp=start_timestamp + ONE_SECOND * 3, - dimensions={'key1': 'value1', 'key2': 'value5', 'key3': 'value7'}), - helpers.create_metric( - name=name2, timestamp=start_timestamp + ONE_SECOND * 3 + 10, - dimensions={'key1': 'value2', 'key2': 'value5', 'key3': 'value7'}), - helpers.create_metric( - name=name2, timestamp=start_timestamp + ONE_SECOND * 3 + 20, - dimensions={'key1': 'value3', 'key2': 'value6', 'key3': 'value7'}), - helpers.create_metric( - name=name2, timestamp=start_timestamp + ONE_SECOND * 3 + 30, - dimensions={'key1': 'value4', 'key2': 'value6', 'key3': 'value8'}) - ] - cls.monasca_client.create_metrics(metric3) - - # Create metric3 for test_list_measurements_with_no_merge_metrics - metric4 = helpers.create_metric( - name=name1, timestamp=start_timestamp + ONE_SECOND * 4, - dimensions={'key-1': 'value-1'}, - value=NUM_MEASUREMENTS + 1) - cls.monasca_client.create_metrics(metric4) - - end_time = str(helpers.timestamp_to_iso( - start_timestamp + NUM_MEASUREMENTS + ONE_SECOND * 5)) - queries = [] - queries.append('?name={}&start_time={}&end_time={}&merge_metrics=true'. - format(name1, start_time, end_time)) - queries.append('?name={}&start_time={}&end_time={}&merge_metrics=true'. - format(name2, start_time, end_time)) - - for timer in range(constants.MAX_RETRIES): - responses = map(cls.monasca_client.list_measurements, queries) - resp_first = responses[0][0] - response_body_first = responses[0][1] - resp_second = responses[1][0] - response_body_second = responses[1][1] - if resp_first.status == 200 and resp_second.status == 200 \ - and len(response_body_first['elements']) == 1 \ - and len(response_body_second['elements']) == 1: - len_meas_first = len( - response_body_first['elements'][0]['measurements']) - len_meas_second = len( - response_body_second['elements'][0]['measurements']) - if len_meas_first == NUM_MEASUREMENTS + 2 \ - and len_meas_second == 4: - break - else: - time.sleep(constants.RETRY_WAIT_SECS) - else: - time.sleep(constants.RETRY_WAIT_SECS) - - cls._start_time = start_time - cls._end_time = end_time - - @decorators.attr(type="gate") - def test_list_measurements(self): - query_parms = '?name=' + str(self._names_list[0]) + \ - '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self._verify_list_measurements(resp, response_body) - elements = response_body['elements'] - self._verify_list_measurements_elements( - elements=elements, test_key=None, test_value=None) - measurements = elements[0]['measurements'] - self._verify_list_measurements_meas_len( - measurements, test_len=NUM_MEASUREMENTS + 2) - i = 0 - for measurement in measurements: - self._verify_list_measurements_measurement(measurement, i) - i += 1 - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_no_start_time(self): - query_parms = '?name=' + str(self._names_list[0]) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_measurements, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_no_name(self): - query_parms = '?start_time=' + str(self._start_time) + '&end_time=' + \ - str(self._end_time) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_measurements, query_parms) - - @decorators.attr(type="gate") - def test_list_measurements_with_dimensions(self): - query_parms = '?name=' + self._names_list[0] + '&start_time=' + \ - str(self._start_time) + '&end_time=' + \ - str(self._end_time) + '&dimensions=' + self._key + ':' \ - + self._value - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self._verify_list_measurements(resp, response_body) - elements = response_body['elements'] - self._verify_list_measurements_elements( - elements=elements, test_key=None, test_value=None) - measurements = elements[0]['measurements'] - self._verify_list_measurements_meas_len(measurements, 1) - measurement = measurements[0] - self._verify_list_measurements_measurement( - measurement=measurement, test_value=NUM_MEASUREMENTS) - - @decorators.attr(type="gate") - def test_list_measurements_with_endtime(self): - time_iso = helpers.timestamp_to_iso( - self._start_timestamp + ONE_SECOND * 2) - query_parms = '?name=' + str(self._names_list[0]) + \ - '&merge_metrics=true' \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(time_iso) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self._verify_list_measurements(resp, response_body) - elements = response_body['elements'] - self._verify_list_measurements_elements(elements=elements, - test_key=None, test_value=None) - measurements = elements[0]['measurements'] - self._verify_list_measurements_meas_len(measurements=measurements, - test_len=NUM_MEASUREMENTS) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_endtime_equals_starttime(self): - query_parms = '?name=' + str(self._names_list[0]) + \ - '&merge_metrics=true' \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._start_time) - self.assertRaises(exceptions.BadRequest, - self.monasca_client.list_measurements, query_parms) - - @decorators.attr(type="gate") - def test_list_measurements_with_offset_limit(self): - query_parms = '?name=' + str(self._names_list[1]) + \ - '&merge_metrics=true&start_time=' + self._start_time + \ - '&end_time=' + self._end_time - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self._verify_list_measurements(resp, response_body) - elements = response_body['elements'] - self._verify_list_measurements_elements(elements=elements, - test_key=None, test_value=None) - measurements = elements[0]['measurements'] - self._verify_list_measurements_meas_len(measurements=measurements, - test_len=4) - - for measurement_index in range(1, len(measurements) - 3): - max_limit = len(measurements) - measurement_index - - # Get first offset from api - query_parms = '?name=' + str(self._names_list[1]) + \ - '&merge_metrics=true&start_time=' + measurements[measurement_index - 1][0] + \ - '&end_time=' + self._end_time + \ - '&limit=1' - resp, response_body = self.monasca_client.list_measurements(query_parms) - for link in response_body['links']: - if link['rel'] == 'next': - next_link = link['href'] - if not next_link: - self.fail("No next link returned with query parameters: {}".formet(query_parms)) - offset = helpers.get_query_param(next_link, "offset") - - first_index = measurement_index + 1 - - for limit in range(1, max_limit): - last_index = measurement_index + limit + 1 - expected_measurements = measurements[first_index:last_index] - - query_parms = '?name=' + str(self._names_list[1]) + \ - '&merge_metrics=true&start_time=' + \ - self._start_time + '&end_time=' + \ - self._end_time + '&limit=' + str(limit) + \ - '&offset=' + str(offset) - - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self._verify_list_measurements(resp, response_body) - new_measurements = response_body['elements'][0]['measurements'] - - self.assertEqual(limit, len(new_measurements)) - for i in range(len(expected_measurements)): - self.assertEqual(expected_measurements[i], - new_measurements[i]) - - @decorators.attr(type="gate") - def test_list_measurements_with_merge_metrics(self): - query_parms = '?name=' + str(self._names_list[0]) + \ - '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self.assertEqual(200, resp.status) - - @decorators.attr(type="gate") - def test_list_measurements_with_group_by_one(self): - query_parms = '?name=' + str(self._names_list[1]) + \ - '&group_by=key2' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 2) - self._verify_list_measurements_elements(elements, None, None) - for measurements in elements: - self.assertEqual(1, len(measurements['dimensions'].keys())) - self.assertEqual([u'key2'], measurements['dimensions'].keys()) - - @decorators.attr(type="gate") - def test_list_measurements_with_group_by_multiple(self): - query_parms = '?name=' + str(self._names_list[1]) + \ - '&group_by=key2,key3' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 3) - self._verify_list_measurements_elements(elements, None, None) - for measurements in elements: - self.assertEqual(2, len(measurements['dimensions'].keys())) - self.assertEqual({u'key2', u'key3'}, set(measurements['dimensions'].keys())) - - @decorators.attr(type="gate") - def test_list_measurements_with_group_by_all(self): - query_parms = '?name=' + str(self._names_list[1]) + \ - '&group_by=*' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 4) - self._verify_list_measurements_elements(elements, None, None) - - @decorators.attr(type="gate") - def test_list_measurements_with_group_by_and_merge(self): - query_parms = '?name=' + str(self._names_list[1]) + \ - '&group_by=*' + \ - '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - resp, response_body = self.monasca_client.list_measurements( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 4) - self._verify_list_measurements_elements(elements, None, None) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_name_exceeds_max_length(self): - long_name = "x" * (constants.MAX_LIST_MEASUREMENTS_NAME_LENGTH + 1) - query_parms = '?name=' + str(long_name) + '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time) + \ - '&end_time=' + str(self._end_time) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_measurements, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_no_merge_metrics(self): - query_parms = '?name=' + str(self._names_list[0]) + \ - '&start_time=' + str(self._start_time) + '&end_time=' \ - + str(self._end_time) - self.assertRaises(exceptions.Conflict, - self.monasca_client.list_measurements, query_parms) - - @decorators.attr(type="gate") - def test_list_measurements_with_duplicate_query_param_merges_positive( - self): - queries = [] - queries.append('?name={}&merge_metrics=true&start_time={}&end_time={' - '}&merge_metrics=true'. - format(self._names_list[0], self._start_time, - self._end_time)) - queries.append('?name={}&merge_metrics=true&start_time={}&end_time={' - '}&merge_metrics=false'. - format(self._names_list[0], self._start_time, - self._end_time)) - responses = map(self.monasca_client.list_measurements, queries) - for i in range(2): - self._verify_list_measurements(responses[i][0], responses[i][1]) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_measurements_with_duplicate_query_param_merges_negative( - self): - queries = [] - queries.append('?name={}&merge_metrics=false&start_time={}&end_time={' - '}&merge_metrics=true'. - format(self._names_list[0], self._start_time, - self._end_time)) - queries.append('?name={}&merge_metrics=false&start_time={}&end_time={' - '}&merge_metrics=false'. - format(self._names_list[0], self._start_time, - self._end_time)) - for i in range(2): - self.assertRaises(exceptions.Conflict, - self.monasca_client.list_measurements, - queries[i]) - - def _verify_list_measurements_measurement(self, measurement, test_value): - self.assertEqual(test_value, float(measurement[1])) - - def _verify_list_measurements(self, resp, response_body): - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - - def _verify_list_measurements_elements(self, elements, test_key, - test_value): - if not elements: - error_msg = "Failed: at least one element is needed. " \ - "Number of element = 0." - self.fail(error_msg) - - for element in elements: - # element = elements[0] - self.assertEqual(set(element), - set(['columns', 'dimensions', 'id', - 'measurements', 'name'])) - self.assertTrue(type(element['name']) is unicode) - self.assertTrue(type(element['dimensions']) is dict) - self.assertTrue(type(element['columns']) is list) - self.assertTrue(type(element['measurements']) is list) - self.assertEqual(set(element['columns']), - set(['timestamp', 'value', 'value_meta'])) - self.assertTrue(str(element['id']) is not None) - if test_key is not None and test_value is not None: - self.assertEqual(str(element['dimensions'][test_key]), - test_value) - - def _verify_list_measurements_meas_len(self, measurements, test_len): - if measurements: - len_measurements = len(measurements) - self.assertEqual(len_measurements, test_len) - else: - error_msg = "Failed: one specific measurement is needed. " \ - "Number of measurements = 0" - self.fail(error_msg) diff --git a/monasca_tempest_tests/tests/api/test_metrics.py b/monasca_tempest_tests/tests/api/test_metrics.py deleted file mode 100644 index fd9f63b8b..000000000 --- a/monasca_tempest_tests/tests/api/test_metrics.py +++ /dev/null @@ -1,711 +0,0 @@ -# -*- coding: utf-8 -*- -# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP -# -# 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. - -# TODO(RMH): Check if ' should be added in the list of INVALID_CHARS. -# TODO(RMH): test_create_metric_no_value, should return 422 if value not sent -import time - -from six.moves import urllib_parse as urlparse - -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers - - -class TestMetrics(base.BaseMonascaTest): - - @decorators.attr(type='gate') - def test_create_metric(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - end_timestamp = int(round((time.time() + 3600 * 24) * 1000)) - end_time_iso = helpers.timestamp_to_iso(end_timestamp) - value_meta_key = data_utils.rand_name('value_meta_key') - value_meta_value = data_utils.rand_name('value_meta_value') - metric = helpers.create_metric(name=name, - dimensions={key: value}, - timestamp=timestamp, - value=1.23, - value_meta={ - value_meta_key: value_meta_value - }) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?name=' + name + '&start_time=' + time_iso + \ - '&end_time=' + end_time_iso - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.\ - list_measurements(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name: - self._verify_list_measurements_element(element, key, value) - measurement = element['measurements'][0] - self._verify_list_measurements_measurement( - measurement, metric, value_meta_key, value_meta_value) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_create_metric: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_create_metric_with_multibyte_character(self): - name = data_utils.rand_name('name').decode('utf8') - key = data_utils.rand_name('key').decode('utf8') - value = data_utils.rand_name('value').decode('utf8') - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - end_timestamp = int(round((time.time() + 3600 * 24) * 1000)) - end_time_iso = helpers.timestamp_to_iso(end_timestamp) - value_meta_key = data_utils.rand_name('value_meta_key').decode('utf8') - value_meta_value = data_utils.rand_name('value_meta_value').decode('utf8') - metric = helpers.create_metric(name=name, - dimensions={key: value}, - timestamp=timestamp, - value=1.23, - value_meta={ - value_meta_key: value_meta_value - }) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?name=' + urlparse.quote(name.encode('utf8')) + \ - '&start_time=' + time_iso + '&end_time=' + end_time_iso - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.\ - list_measurements(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if element['name'] == name: - self._verify_list_measurements_element(element, key, value) - measurement = element['measurements'][0] - self._verify_list_measurements_measurement( - measurement, metric, value_meta_key, value_meta_value) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_create_metric: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_create_metrics(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - end_timestamp = int(round(timestamp + 3600 * 24 * 1000)) - end_time_iso = helpers.timestamp_to_iso(end_timestamp) - value_meta_key1 = data_utils.rand_name('meta_key') - value_meta_value1 = data_utils.rand_name('meta_value') - value_meta_key2 = data_utils.rand_name('value_meta_key') - value_meta_value2 = data_utils.rand_name('value_meta_value') - metrics = [ - helpers.create_metric(name=name, - dimensions={key: value}, - timestamp=timestamp, - value=1.23, - value_meta={ - value_meta_key1: value_meta_value1 - }), - helpers.create_metric(name=name, - dimensions={key: value}, - timestamp=timestamp + 6000, - value=4.56, - value_meta={ - value_meta_key2: value_meta_value2 - }) - ] - resp, response_body = self.monasca_client.create_metrics(metrics) - self.assertEqual(204, resp.status) - query_param = '?name=' + name + '&start_time=' + str(time_iso) + \ - '&end_time=' + str(end_time_iso) - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.\ - list_measurements(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name \ - and len(element['measurements']) == 2: - self._verify_list_measurements_element(element, key, value) - first_measurement = element['measurements'][0] - second_measurement = element['measurements'][1] - self._verify_list_measurements_measurement( - first_measurement, metrics[0], value_meta_key1, - value_meta_value1) - self._verify_list_measurements_measurement( - second_measurement, metrics[1], value_meta_key2, - value_meta_value2) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_create_metrics: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_no_name(self): - metric = helpers.create_metric(name=None) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_empty_name(self): - metric = helpers.create_metric(name='') - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_empty_value_in_dimensions(self): - name = data_utils.rand_name('name') - metric = helpers.create_metric(name=name, - dimensions={'key': ''}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_empty_key_in_dimensions(self): - name = data_utils.rand_name('name') - metric = helpers.create_metric(name=name, - dimensions={'': 'value'}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - def test_create_metric_with_no_dimensions(self): - name = data_utils.rand_name('name') - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - end_timestamp = int(round(timestamp + 3600 * 24 * 1000)) - end_time_iso = helpers.timestamp_to_iso(end_timestamp) - value_meta_key = data_utils.rand_name('value_meta_key') - value_meta_value = data_utils.rand_name('value_meta_value') - metric = helpers.create_metric(name=name, - dimensions=None, - timestamp=timestamp, - value=1.23, - value_meta={ - value_meta_key: value_meta_value}) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?name=' + str(name) + '&start_time=' + str(time_iso) \ - + '&end_time=' + str(end_time_iso) - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.\ - list_measurements(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name: - self._verify_list_measurements_element( - element, test_key=None, test_value=None) - if len(element['measurements']) > 0: - measurement = element['measurements'][0] - self._verify_list_measurements_measurement( - measurement, metric, value_meta_key, - value_meta_value) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_create_metric_with_no_dimensions: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_create_metric_with_colon_in_dimension_value(self): - name = data_utils.rand_name('name') - key = 'url' - value = 'http://localhost:8070/v2.0' - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - end_timestamp = int(round((time.time() + 3600 * 24) * 1000)) - end_time_iso = helpers.timestamp_to_iso(end_timestamp) - metric = helpers.create_metric(name=name, - dimensions={key: value}) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?name=' + name + '&start_time=' + time_iso + \ - '&end_time=' + end_time_iso + \ - '&dimensions=' + key + ':' + value - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client. \ - list_measurements(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name: - self._verify_list_measurements_element(element, key, value) - measurement = element['measurements'][0] - self._verify_list_measurements_measurement( - measurement, metric, None, None) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_create_metric: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_no_timestamp(self): - metric = helpers.create_metric() - metric['timestamp'] = None - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_no_value(self): - timestamp = int(round(time.time() * 1000)) - metric = helpers.create_metric(timestamp=timestamp, - value=None) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_name_exceeds_max_length(self): - long_name = "x" * (constants.MAX_METRIC_NAME_LENGTH + 1) - metric = helpers.create_metric(long_name) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_invalid_chars_in_name(self): - for invalid_char in constants.INVALID_NAME_CHARS: - metric = helpers.create_metric(invalid_char) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_invalid_chars_in_dimensions(self): - for invalid_char in constants.INVALID_DIMENSION_CHARS: - metric = helpers.create_metric('name-1', {'key-1': invalid_char}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - for invalid_char in constants.INVALID_DIMENSION_CHARS: - metric = helpers.create_metric('name-1', {invalid_char: 'value-1'}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_dimension_key_exceeds_max_length(self): - long_key = "x" * (constants.MAX_DIMENSION_KEY_LENGTH + 1) - metric = helpers.create_metric('name-1', {long_key: 'value-1'}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_dimension_value_exceeds_max_length(self): - long_value = "x" * (constants.MAX_DIMENSION_VALUE_LENGTH + 1) - metric = helpers.create_metric('name-1', {'key-1': long_value}) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_value_meta_name_exceeds_max_length(self): - long_value_meta_name = "x" * (constants.MAX_VALUE_META_NAME_LENGTH + 1) - value_meta_dict = {long_value_meta_name: "value_meta_value"} - metric = helpers.create_metric(name='name', value_meta=value_meta_dict) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_with_value_meta_exceeds_max_length(self): - value_meta_name = "x" - long_value_meta_value = "y" * constants.MAX_VALUE_META_TOTAL_LENGTH - value_meta_dict = {value_meta_name: long_value_meta_value} - metric = helpers.create_metric(name='name', value_meta=value_meta_dict) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.create_metrics, - metric) - - @decorators.attr(type='gate') - def test_list_metrics(self): - resp, response_body = self.monasca_client.list_metrics() - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - elements = response_body['elements'] - element = elements[0] - self._verify_list_metrics_element(element, test_key=None, - test_value=None, test_name=None) - self.assertTrue(set(['id', 'name', 'dimensions']) == set(element)) - - @decorators.attr(type='gate') - def test_list_metrics_with_dimensions(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - metric = helpers.create_metric(name=name, dimensions={key: value}) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?dimensions=' + key + ':' + value - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['dimensions'][key]) == value: - self._verify_list_metrics_element(element, test_name=name) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_list_metrics_with_dimensions: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_list_metrics_dimension_query_multi_value_with_diff_names(self): - metrics, name, key_service, values = \ - self._create_metrics_with_different_dimensions(same_name=False) - metric_dimensions = self._get_metric_dimensions( - key_service, values, same_metric_name=False) - query_param = '?dimensions=' + key_service + ':' + values[0] + '|' +\ - values[1] - self._verify_dimensions(query_param, metric_dimensions) - - @decorators.attr(type='gate') - def test_list_metrics_dimension_query_no_value_with_diff_names(self): - metrics, name, key_service, values = \ - self._create_metrics_with_different_dimensions(same_name=False) - metric_dimensions = self._get_metric_dimensions( - key_service, values, same_metric_name=False) - query_param = '?dimensions=' + key_service - self._verify_dimensions(query_param, metric_dimensions) - - @decorators.attr(type='gate') - def test_list_metrics_dimension_query_multi_value_with_same_name(self): - # Skip the test for now due to InfluxDB Inconsistency - return - metrics, name, key_service, values = \ - self._create_metrics_with_different_dimensions(same_name=True) - metric_dimensions = self._get_metric_dimensions( - key_service, values, same_metric_name=True) - query_param = '?name=' + name + '&dimensions=' + key_service + ':' +\ - values[0] + '|' + values[1] - self._verify_dimensions(query_param, metric_dimensions) - - @decorators.attr(type='gate') - def test_list_metrics_dimension_query_no_value_with_same_name(self): - # Skip the test for now due to InfluxDB Inconsistency - return - metrics, name, key_service, values = \ - self._create_metrics_with_different_dimensions(same_name=True) - metric_dimensions = self._get_metric_dimensions( - key_service, values, same_metric_name=True) - query_param = '?name=' + name + '&dimensions=' + key_service - self._verify_dimensions(query_param, metric_dimensions) - - @decorators.attr(type='gate') - def test_list_metrics_with_name(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - metric = helpers.create_metric(name=name, - dimensions={key: value}) - resp, response_body = self.monasca_client.create_metrics(metric) - self.assertEqual(204, resp.status) - query_param = '?name=' + str(name) - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name: - self._verify_list_metrics_element(element, test_key=key, - test_value=value) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_list_metrics_with_name: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_list_metrics_with_project(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - project = self.projects_client.create_project( - name=data_utils.rand_name('test_project'))['project'] - # Delete the project at the end of the test - self.addCleanup(self.projects_client.delete_project, project['id']) - metric = helpers.create_metric(name=name, - dimensions={key: value}) - resp, response_body = self.monasca_client.create_metrics( - metric, tenant_id=project['id']) - self.assertEqual(204, resp.status) - query_param = '?tenant_id=' + str(project['id']) - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == name: - self._verify_list_metrics_element(element, test_key=key, - test_value=value) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Failed test_list_metrics_with_tenant: " \ - "timeout on waiting for metrics: at least " \ - "one metric is needed. Current number of " \ - "metrics = 0" - self.fail(error_msg) - - @decorators.attr(type='gate') - def test_list_metrics_with_offset_limit(self): - name = data_utils.rand_name() - key1 = data_utils.rand_name() - key2 = data_utils.rand_name() - - metrics = [ - helpers.create_metric(name=name, dimensions={ - key1: 'value-1', key2: 'value-1'}), - helpers.create_metric(name=name, dimensions={ - key1: 'value-2', key2: 'value-2'}), - helpers.create_metric(name=name, dimensions={ - key1: 'value-3', key2: 'value-3'}), - helpers.create_metric(name=name, dimensions={ - key1: 'value-4', key2: 'value-4'}) - ] - self.monasca_client.create_metrics(metrics) - query_param = '?name=' + name - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_param) - elements = response_body['elements'] - if elements and len(elements) == 4: - break - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = ("Failed test_list_metrics_with_offset_limit: " - "timeout on waiting for metrics: 4 metrics " - "are needed. Current number of elements = " - "{}").format(len(elements)) - self.fail(error_msg) - - first_element = elements[0] - query_parms = '?name=' + name + '&limit=4' - resp, response_body = self.monasca_client.list_metrics(query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(4, len(elements)) - self.assertEqual(first_element, elements[0]) - - for metric_index in range(len(elements) - 1): - metric = elements[metric_index] - max_limit = 3 - metric_index - - for limit in range(1, max_limit): - first_index = metric_index + 1 - last_index = first_index + limit - expected_elements = elements[first_index:last_index] - - query_parms = '?name=' + name + '&offset=' + \ - str(metric['id']) + '&limit=' + \ - str(limit) - resp, response_body = self.\ - monasca_client.list_metrics(query_parms) - self.assertEqual(200, resp.status) - new_elements = response_body['elements'] - - self.assertEqual(limit, len(new_elements)) - for i in range(len(expected_elements)): - self.assertEqual(expected_elements[i], new_elements[i]) - - def _verify_list_measurements_element(self, element, test_key, test_value): - self.assertEqual(set(element), - set(['columns', 'dimensions', 'id', 'measurements', - 'name'])) - self.assertEqual(set(element['columns']), - set(['timestamp', 'value', 'value_meta'])) - self.assertTrue(str(element['id']) is not None) - if test_key is not None and test_value is not None: - self.assertEqual( - element['dimensions'][test_key].encode('utf-8'), - test_value.encode('utf-8') - ) - - def _verify_list_measurements_measurement(self, measurement, - test_metric, test_vm_key, - test_vm_value): - # Timestamps stored in influx sometimes are 1 millisecond different to - # the value stored by the persister. Check if the timestamps are - # equal in one millisecond range to pass the test. - time_iso_millis = helpers.timestamp_to_iso_millis( - test_metric['timestamp'] + 0) - time_iso_millis_plus = helpers.timestamp_to_iso_millis( - test_metric['timestamp'] + 1) - time_iso_millis_minus = helpers.timestamp_to_iso_millis( - test_metric['timestamp'] - 1) - if str(measurement[0]) != time_iso_millis and str(measurement[0]) != \ - time_iso_millis_plus and str(measurement[0]) != \ - time_iso_millis_minus: - error_msg = ("Mismatch Error: None of {}, {}, {} matches {}").\ - format(time_iso_millis, time_iso_millis_plus, - time_iso_millis_minus, str(measurement[0])) - self.fail(error_msg) - self.assertEqual(measurement[1], test_metric['value']) - if test_vm_key is not None and test_vm_value is not None: - self.assertEqual( - measurement[2][test_vm_key].encode('utf-8'), - test_vm_value.encode('utf-8') - ) - - def _verify_list_metrics_element(self, element, test_key=None, - test_value=None, test_name=None): - self.assertTrue(type(element['id']) is unicode) - self.assertTrue(type(element['name']) is unicode) - self.assertTrue(type(element['dimensions']) is dict) - self.assertEqual(set(element), set(['dimensions', 'id', 'name'])) - self.assertTrue(str(element['id']) is not None) - if test_key is not None and test_value is not None: - self.assertEqual(str(element['dimensions'][test_key]), test_value) - if test_name is not None: - self.assertEqual(str(element['name']), test_name) - - @decorators.attr(type='gate') - def test_list_metrics_with_time_args(self): - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value_org = data_utils.rand_name('value') - - now = int(round(time.time() * 1000)) - # - # Built start and end time args before and after the measurement. - # - start_iso = helpers.timestamp_to_iso(now - 1000) - end_timestamp = int(round(now + 1000)) - end_iso = helpers.timestamp_to_iso(end_timestamp) - - metric = helpers.create_metric(name=name, - dimensions={key: value_org}, - timestamp=now) - - self.monasca_client.create_metrics(metric) - for timer in range(constants.MAX_RETRIES): - query_parms = '?name=' + name + '&start_time=' + start_iso + '&end_time=' + end_iso - resp, response_body = self.monasca_client.list_metrics(query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - if elements: - dimensions = elements[0] - dimension = dimensions['dimensions'] - value = dimension[unicode(key)] - self.assertEqual(value_org, str(value)) - break - else: - time.sleep(constants.RETRY_WAIT_SECS) - if timer == constants.MAX_RETRIES - 1: - skip_msg = "Skipped test_list_metrics_with_time_args: " \ - "timeout on waiting for metrics: at least one " \ - "metric is needed. Current number of metrics " \ - "= 0" - raise self.skipException(skip_msg) - - @staticmethod - def _get_metric_dimensions(key_service, values, same_metric_name): - if same_metric_name: - metric_dimensions = [{key_service: values[0], 'key3': ''}, - {key_service: values[1], 'key3': ''}, - {key_service: '', 'key3': 'value3'}] - else: - metric_dimensions = [{key_service: values[0]}, - {key_service: values[1]}, - {'key3': 'value3'}] - return metric_dimensions - - def _verify_dimensions(self, query_param, metric_dimensions): - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_param) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - if len(elements) == 2: - dimension_sets = [] - for element in elements: - dimension_sets.append(element['dimensions']) - self.assertIn(metric_dimensions[0], dimension_sets) - self.assertIn(metric_dimensions[1], dimension_sets) - self.assertNotIn(metric_dimensions[2], dimension_sets) - return - time.sleep(constants.RETRY_WAIT_SECS) - if i == constants.MAX_RETRIES - 1: - error_msg = "Timeout on waiting for metrics: at least " \ - "2 metrics are needed. Current number of " \ - "metrics = {}".format(len(elements)) - self.fail(error_msg) - - def _create_metrics_with_different_dimensions(self, same_name=True): - name1 = data_utils.rand_name('name1') - name2 = name1 if same_name else data_utils.rand_name('name2') - name3 = name1 if same_name else data_utils.rand_name('name3') - key_service = data_utils.rand_name('service') - values = [data_utils.rand_name('value1'), - data_utils.rand_name('value2')] - metrics = [helpers.create_metric(name1, {key_service: values[0]}), - helpers.create_metric(name2, {key_service: values[1]}), - helpers.create_metric(name3, {'key3': 'value3'})] - resp, response_body = self.monasca_client.create_metrics(metrics) - self.assertEqual(204, resp.status) - return metrics, name1, key_service, values diff --git a/monasca_tempest_tests/tests/api/test_metrics_names.py b/monasca_tempest_tests/tests/api/test_metrics_names.py deleted file mode 100644 index 4ff87b861..000000000 --- a/monasca_tempest_tests/tests/api/test_metrics_names.py +++ /dev/null @@ -1,162 +0,0 @@ -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from urllib import urlencode - - -class TestMetricsNames(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestMetricsNames, cls).resource_setup() - name1 = data_utils.rand_name('name1') - name2 = data_utils.rand_name('name2') - name3 = data_utils.rand_name('name3') - key = data_utils.rand_name() - key1 = data_utils.rand_name() - value = data_utils.rand_name() - value1 = data_utils.rand_name() - - timestamp = int(round(time.time() * 1000)) - time_iso = helpers.timestamp_to_iso(timestamp) - - metric1 = helpers.create_metric(name=name1, - dimensions={key: value}) - metric2 = helpers.create_metric(name=name2, - dimensions={key1: value1}) - metric3 = helpers.create_metric(name=name3, - dimensions={key: value}) - cls._test_metric_names = {name1, name2, name3} - cls._expected_names_list = list(cls._test_metric_names) - cls._expected_names_list.sort() - cls._test_metric_names_with_same_dim = [name1, name3] - cls._test_metrics = [metric1, metric2, metric3] - cls._dimensions_param = key + ':' + value - - cls.monasca_client.create_metrics(cls._test_metrics) - - query_param = '?start_time=' + time_iso - returned_name_set = set() - for i in range(constants.MAX_RETRIES): - resp, response_body = cls.monasca_client.list_metrics(query_param) - elements = response_body['elements'] - for element in elements: - returned_name_set.add(str(element['name'])) - if cls._test_metric_names.issubset(returned_name_set): - return - time.sleep(constants.RETRY_WAIT_SECS) - - assert False, 'Unable to initialize metrics' - - @classmethod - def resource_cleanup(cls): - super(TestMetricsNames, cls).resource_cleanup() - - @decorators.attr(type='gate') - def test_list_metrics_names(self): - resp, response_body = self.monasca_client.list_metrics_names() - metric_names = self._verify_response(resp, response_body) - self.assertEqual(metric_names, self._expected_names_list) - - @decorators.attr(type='gate') - def test_list_metrics_names_with_dimensions(self): - query_params = '?dimensions=' + self._dimensions_param - resp, response_body = self.monasca_client.list_metrics_names( - query_params) - metric_names = self._verify_response(resp, response_body) - self.assertEqual(metric_names, - self._test_metric_names_with_same_dim) - - @decorators.attr(type='gate') - def test_list_metrics_names_with_limit_offset(self): - resp, response_body = self.monasca_client.list_metrics_names() - self.assertEqual(200, resp.status) - elements = response_body['elements'] - num_names = len(elements) - - for limit in range(1, num_names): - start_index = 0 - params = [('limit', limit)] - offset = None - while True: - num_expected_elements = limit - if (num_expected_elements + start_index) > num_names: - num_expected_elements = num_names - start_index - - these_params = list(params) - # If not the first call, use the offset returned by the last - # call - if offset: - these_params.extend([('offset', str(offset))]) - query_params = '?' + urlencode(these_params) - - resp, response_body = \ - self.monasca_client.list_metrics_names(query_params) - new_elements = self._verify_response(resp, response_body) - self.assertEqual(num_expected_elements, len(new_elements)) - - expected_elements = elements[start_index:start_index + limit] - expected_names = \ - [expected_elements[i]['name'] for i in range( - len(expected_elements))] - - self.assertEqual(expected_names, new_elements) - start_index += num_expected_elements - if start_index >= num_names: - break - # Get the next set - offset = self._get_offset(response_body) - - @decorators.attr(type='gate') - def test_list_metrics_names_with_offset_not_in_metrics_names_list(self): - offset1 = 'tempest-abc' - offset2 = 'tempest-name111' - offset3 = 'tempest-name4-random' - query_param1 = '?' + urlencode([('offset', offset1)]) - query_param2 = '?' + urlencode([('offset', offset2)]) - query_param3 = '?' + urlencode([('offset', offset3)]) - - resp, response_body = self.monasca_client.list_metrics_names( - query_param1) - metric_names = self._verify_response(resp, response_body) - - self.assertEqual(metric_names, self._expected_names_list[:]) - - resp, response_body = self.monasca_client.list_metrics_names( - query_param2) - metric_names = self._verify_response(resp, response_body) - self.assertEqual(metric_names, self._expected_names_list[1:]) - - resp, response_body = self.monasca_client.list_metrics_names( - query_param3) - self.assertEqual(response_body['elements'], []) - - def _verify_response(self, resp, response_body): - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - - response_names_length = len(response_body['elements']) - if response_names_length == 0: - self.fail("No metric names returned") - - metric_names = [str(response_body['elements'][i]['name']) for i in - range(response_names_length)] - return metric_names diff --git a/monasca_tempest_tests/tests/api/test_notification_method_type.py b/monasca_tempest_tests/tests/api/test_notification_method_type.py deleted file mode 100644 index 6f2bc3002..000000000 --- a/monasca_tempest_tests/tests/api/test_notification_method_type.py +++ /dev/null @@ -1,33 +0,0 @@ -# (C) Copyright 2016-2017 Hewlett Packard Enterprise Development LP -# -# 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 monasca_tempest_tests.tests.api import base -from tempest.lib import decorators - - -class TestNotificationMethodType(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestNotificationMethodType, cls).resource_setup() - - @classmethod - def resource_cleanup(cls): - super(TestNotificationMethodType, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_list_notification_method_type(self): - resp, response_body = (self.monasca_client. - list_notification_method_types()) - self.assertEqual(200, resp.status) diff --git a/monasca_tempest_tests/tests/api/test_notification_methods.py b/monasca_tempest_tests/tests/api/test_notification_methods.py deleted file mode 100644 index adc228a26..000000000 --- a/monasca_tempest_tests/tests/api/test_notification_methods.py +++ /dev/null @@ -1,1075 +0,0 @@ -# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP -# -# 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 time - -import six.moves.urllib.parse as urlparse - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions - -DEFAULT_EMAIL_ADDRESS = 'john.doe@domain.com' - - -class TestNotificationMethods(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestNotificationMethods, cls).resource_setup() - - @classmethod - def resource_cleanup(cls): - super(TestNotificationMethods, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_create_notification_method(self): - notification = helpers.create_notification() - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_email_notification_method_with_lower_case_type(self): - notification = helpers.create_notification(name='lower case email notification', - type='email') - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_email_notification_method_with_mixed_case_type(self): - notification = helpers.create_notification(name='mixed case email notification', - type='EmAil') - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_notification_method_period_not_defined(self): - notification = helpers.create_notification(period=None) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_webhook_notification_method_with_non_zero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_notification_method_webhook_test_tld(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://mytest.test/webhook', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_notification_method_webhook_test_tld_and_port(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://mytest.test:4533/webhook', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_no_name(self): - notification = helpers.create_notification(name=None) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_no_type(self): - notification = helpers.create_notification(type=None) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_no_address(self): - notification = helpers.create_notification(address=None) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_name_exceeds_max_length(self): - long_name = "x" * (constants.MAX_NOTIFICATION_METHOD_NAME_LENGTH + 1) - notification = helpers.create_notification(name=long_name) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_address_exceeds_max_length(self): - long_address = "x" * ( - constants.MAX_NOTIFICATION_METHOD_ADDRESS_LENGTH + 1) - notification = helpers.create_notification(address=long_address) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_email_address(self): - notification = helpers.create_notification(address="name@") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_scheme_webhook(self): - notification = helpers.create_notification(type="WEBHOOK", - address="ftp://localhost") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_webhook_address(self): - notification = helpers.create_notification(type="WEBHOOK", - address="localhost:123") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - # The below tests are making sure that we accept passing in case insensitive types and that we still validate the - # address if the types are case insensitive - @decorators.attr(type="gate") - def test_create_notification_method_webhook_with_lower_case_type(self): - notification = helpers.create_notification(type='webhook', - address='http://mytest.test:4533') - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_notification_method_webhook_with_mixed_case_type(self): - notification = helpers.create_notification(type='webHooK', - address='http://mytest.test:4533') - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_email_address_type_all_lower_case(self): - notification = helpers.create_notification(type="email", - address="name@") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_email_address_type_all_mixed_case(self): - notification = helpers.create_notification(type="EmAil", - address="name@") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_webhook_address_type_mixed_case(self): - notification = helpers.create_notification(type="WebHook", - address="localhost:123") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_webhook_address_type_lower_case(self): - notification = helpers.create_notification(type="webhook", - address="localhost:123") - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_type(self): - notification = helpers.create_notification(type='random') - self.assertRaises((exceptions.BadRequest, exceptions.NotFound, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_float_period(self): - notification = helpers.create_notification(period=1.2) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_method_with_invalid_string_period(self): - notification = helpers.create_notification(period='random') - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_email_notification_method_with_invalid_non_zero_period(self): - notification = helpers.create_notification(period=60) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_pagerduty_notification_method_with_invalid_non_zero_period(self): - notification = helpers.create_notification(type='PAGERDUTY', - address='test03@localhost', - period=60) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_webhook_notification_method_with_invalid_period(self): - notification = helpers.create_notification(type='WEBHOOK', - address='http://localhost/test01', - period=10) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.create_notifications, - notification) - - @decorators.attr(type="gate") - def test_list_notification_methods(self): - notification = helpers.create_notification() - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - resp, response_body = self.monasca_client.list_notification_methods() - self.assertEqual(200, resp.status) - # Test response body - self.assertTrue(set(['links', 'elements']) == set(response_body)) - elements = response_body['elements'] - element = elements[0] - self.assertTrue(set(['id', 'links', 'name', 'type', 'address', 'period']) == - set(element)) - self.assertTrue(type(element['id']) is unicode) - self.assertTrue(type(element['links']) is list) - self.assertTrue(type(element['name']) is unicode) - self.assertTrue(type(element['type']) is unicode) - self.assertTrue(type(element['address']) is unicode) - - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_list_notification_methods_sort_by(self): - notifications = [helpers.create_notification( - name='notification sort by 01', - type='PAGERDUTY', - address='test03@localhost', - ), helpers.create_notification( - name='notification sort by 02', - type='WEBHOOK', - address='http://localhost/test01', - ), helpers.create_notification( - name='notification sort by 03', - type='EMAIL', - address='test02@localhost', - )] - for notification in notifications: - resp, response_body = self.monasca_client.create_notifications(notification) - notification['id'] = response_body['id'] - time.sleep(1) - - sort_params1 = ['id', 'name', 'type', 'address'] - for sort_by in sort_params1: - notif_sorted_by = sorted(notifications, - key=lambda obj: obj[sort_by]) - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notif_sorted_by[i][sort_by], element[sort_by]) - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by + urlparse.quote(' asc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notif_sorted_by[i][sort_by], element[sort_by]) - - notif_sorted_by_reverse = sorted(notifications, - key=lambda obj: obj[sort_by], - reverse=True) - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by + urlparse.quote(' desc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notif_sorted_by_reverse[i][sort_by], element[sort_by]) - - sort_params2 = ['created_at', 'updated_at'] - for sort_by in sort_params2: - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notifications[i]['id'], element['id']) - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by + urlparse.quote(' asc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notifications[i]['id'], element['id']) - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + sort_by + urlparse.quote(' desc')) - self.assertEqual(200, resp.status) - for i, element in enumerate(response_body['elements']): - self.assertEqual(notifications[-i - 1]['id'], element['id']) - - for notification in notifications: - self.monasca_client.delete_notification_method(notification['id']) - - @decorators.attr(type="gate") - def test_list_notification_methods_multiple_sort_by(self): - notifications = [helpers.create_notification( - name='notification sort by 01', - type='EMAIL', - address='test02@localhost', - ), helpers.create_notification( - name='notification sort by 02', - type='PAGERDUTY', - address='test03@localhost', - ), helpers.create_notification( - name='notification sort by 03', - type='EMAIL', - address='test04@localhost', - ), helpers.create_notification( - name='notification sort by 04', - type='EMAIL', - address='test01@localhost', - )] - for notification in notifications: - resp, response_body = self.monasca_client.create_notifications(notification) - notification['id'] = response_body['id'] - - resp, response_body = self.monasca_client.list_notification_methods( - '?sort_by=' + urlparse.quote('type asc,address desc,id')) - self.assertEqual(200, resp.status) - - expected_order = [2, 0, 3, 1] - - for i, element in enumerate(response_body['elements']): - self.assertEqual(notifications[expected_order[i]]['id'], element['id']) - - for element in response_body['elements']: - self.monasca_client.delete_notification_method(element['id']) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_notification_methods_invalid_sort_by(self): - query_parms = '?sort_by=random' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_notification_methods, - query_parms) - - @decorators.attr(type="gate") - def test_list_notification_methods_with_offset_limit(self): - name1 = data_utils.rand_name('notification') - name2 = data_utils.rand_name('notification') - name3 = data_utils.rand_name('notification') - name4 = data_utils.rand_name('notification') - notification1 = helpers.create_notification(name=name1) - notification2 = helpers.create_notification(name=name2) - notification3 = helpers.create_notification(name=name3) - notification4 = helpers.create_notification(name=name4) - - resp, response_body = self.monasca_client.create_notifications( - notification1) - id1 = response_body['id'] - self.assertEqual(201, resp.status) - resp, response_body = self.monasca_client.create_notifications( - notification2) - id2 = response_body['id'] - self.assertEqual(201, resp.status) - resp, response_body = self.monasca_client.create_notifications( - notification3) - id3 = response_body['id'] - self.assertEqual(201, resp.status) - resp, response_body = self.monasca_client.create_notifications( - notification4) - id4 = response_body['id'] - self.assertEqual(201, resp.status) - - resp, response_body = self.monasca_client.list_notification_methods() - elements = response_body['elements'] - - first_element = elements[0] - last_element = elements[3] - - query_parms = '?limit=4' - resp, response_body = self.monasca_client.\ - list_notification_methods(query_parms) - self.assertEqual(200, resp.status) - self.assertEqual(4, len(response_body['elements'])) - self.assertEqual(first_element, response_body['elements'][0]) - - timeout = time.time() + 60 * 1 # 1 minute timeout - for limit in range(1, 5): - next_element = elements[limit - 1] - offset = limit - while True: - if time.time() < timeout: - query_parms = '?offset=' + str(offset) + \ - '&limit=' + str(limit) - resp, response_body = self.monasca_client.\ - list_notification_methods(query_parms) - self.assertEqual(200, resp.status) - new_elements = response_body['elements'] - if len(new_elements) > limit - 1: - self.assertEqual(limit, len(new_elements)) - next_element = new_elements[limit - 1] - offset += 1 - elif 0 < len(new_elements) <= limit - 1: - self.assertEqual(last_element, new_elements[0]) - break - else: - self.assertEqual(last_element, next_element) - break - else: - msg = "Failed " \ - "test_list_notification_methods_with_offset_limit:" \ - " one minute timeout on offset limit test loop." - raise exceptions.TimeoutException(msg) - - resp, response_body = self.monasca_client.\ - delete_notification_method(id1) - self.assertEqual(204, resp.status) - - resp, response_body = self.monasca_client.\ - delete_notification_method(id2) - self.assertEqual(204, resp.status) - - resp, response_body = self.monasca_client.\ - delete_notification_method(id3) - self.assertEqual(204, resp.status) - resp, response_body = self.monasca_client.\ - delete_notification_method(id4) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_get_notification_method(self): - notification = helpers.create_notification() - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - resp, response_body = self.monasca_client.get_notification_method(id) - self.assertEqual(200, resp.status) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_get_notification_method_with_invalid_id(self): - notification = helpers.create_notification() - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.get_notification_method, - id) - resp, response_body = self.monasca_client.\ - delete_notification_method(response_body['id']) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_update_notification_method_name(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(name, response_body['name']) - id = response_body['id'] - new_name = name + 'update' - resp, response_body = self.monasca_client.\ - update_notification_method(id, new_name, - type=response_body['type'], - address=response_body['address'], - period=response_body['period']) - self.assertEqual(200, resp.status) - self.assertEqual(new_name, response_body['name']) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_update_notification_method_type(self): - type = 'EMAIL' - notification = helpers.create_notification(type=type) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(type, response_body['type']) - id = response_body['id'] - new_type = 'PAGERDUTY' - resp, response_body = \ - self.monasca_client.\ - update_notification_method(id, name=response_body['name'], - type=new_type, - address=response_body['address'], - period=response_body['period']) - self.assertEqual(200, resp.status) - self.assertEqual(new_type, response_body['type']) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_update_notification_method_address(self): - address = DEFAULT_EMAIL_ADDRESS - notification = helpers.create_notification(address=address) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(address, response_body['address']) - id = response_body['id'] - new_address = 'jane.doe@domain.com' - resp, response_body = self.monasca_client.\ - update_notification_method(id, - name=response_body['name'], - type=response_body['type'], - address=new_address, - period=0) - self.assertEqual(200, resp.status) - self.assertEqual(new_address, response_body['address']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_name_exceeds_max_length(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - new_name_long = "x" * (constants.MAX_NOTIFICATION_METHOD_NAME_LENGTH - + 1) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=new_name_long, type=response_body['type'], - address=response_body['address'], period=response_body['period']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_invalid_type(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.NotFound, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type='random', - address=response_body['address'], period=0) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_address_exceeds_max_length(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - new_address_long = "x" * ( - constants.MAX_NOTIFICATION_METHOD_ADDRESS_LENGTH + 1) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type=response_body['type'], - address=new_address_long, period=response_body['period']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_with_no_address(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises( - (exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method_with_no_address, id, - name="test_update_notification_method_name", - type=response_body['type']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_create_and_delete_notification_method(self): - notification = helpers.create_notification() - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = response_body['id'] - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_delete_notification_method_with_invalid_id(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - id = data_utils.rand_name() - self.assertRaises(exceptions.NotFound, - self.monasca_client.delete_notification_method, - id) - resp, response_body = self.monasca_client.\ - delete_notification_method(response_body['id']) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_notification_method_with_invalid_id(self): - id = data_utils.rand_name() - name = data_utils.rand_name('notification-') - self.assertRaises(exceptions.NotFound, - self.monasca_client.patch_notification_method, - id, name) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_with_invalid_id(self): - id = data_utils.rand_name() - name = data_utils.rand_name('notification-') - self.assertRaises(exceptions.NotFound, - self.monasca_client.update_notification_method, id, - name=name, type='EMAIL', - address='bob@thebridge.org', period=0) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_email_notification_method_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type=response_body['type'], - address=response_body['address'], period=60) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_webhook_notification_method_to_email_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type='EMAIL', - address='test@localhost', period=response_body['period']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_webhook_notification_method_to_pagerduty_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type='PAGERDUTY', - address='test@localhost', period=response_body['period']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_notification_method_with_non_int_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type=response_body['type'], - address=response_body['name'], period='zero') - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_update_webhook_notification_method_with_invalid_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.update_notification_method, id, - name=response_body['name'], type=response_body['type'], - address=response_body['address'], period=5) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_patch_notification_method_name(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(name, response_body['name']) - id = response_body['id'] - new_name = name + 'update' - resp, response_body = self.monasca_client.\ - patch_notification_method(id, new_name) - self.assertEqual(200, resp.status) - self.assertEqual(new_name, response_body['name']) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_patch_notification_method_type(self): - type = 'EMAIL' - notification = helpers.create_notification(type=type) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(type, response_body['type']) - id = response_body['id'] - new_type = 'PAGERDUTY' - resp, response_body = \ - self.monasca_client.\ - patch_notification_method(id, type=new_type) - self.assertEqual(200, resp.status) - self.assertEqual(new_type, response_body['type']) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_patch_notification_method_address(self): - address = DEFAULT_EMAIL_ADDRESS - notification = helpers.create_notification(address=address) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(address, response_body['address']) - id = response_body['id'] - new_address = 'jane.doe@domain.com' - resp, response_body = self.monasca_client.\ - patch_notification_method(id, address=new_address) - self.assertEqual(200, resp.status) - self.assertEqual(new_address, response_body['address']) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - def test_patch_notification_method_address_period(self): - type = 'WEBHOOK' - notification = helpers.create_notification( - type=type, address='http://localhost/test01', period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - self.assertEqual(201, resp.status) - self.assertEqual(type, response_body['type']) - id = response_body['id'] - - # test_patch_webhook_notification_to_email_with_zero_period - new_type = 'EMAIL' - new_period = 0 - resp, response_body = \ - self.monasca_client.\ - patch_notification_method(id, type=new_type, - address='john.doe@domain.com', - period=new_period) - self.assertEqual(200, resp.status) - self.assertEqual(new_type, response_body['type']) - self.assertEqual(new_period, response_body['period']) - - # test_patch_email_notification_to_webhook_with_nonzero_period - new_type = 'WEBHOOK' - new_period = 60 - resp, response_body = \ - self.monasca_client.\ - patch_notification_method(id, type=new_type, - address='http://localhost/test01', - period=new_period) - self.assertEqual(200, resp.status) - self.assertEqual(new_type, response_body['type']) - self.assertEqual(new_period, response_body['period']) - resp, response_body = self.monasca_client.\ - delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_notification_method_name_exceeds_max_length(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - new_name_long = "x" * (constants.MAX_NOTIFICATION_METHOD_NAME_LENGTH - + 1) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, - name=new_name_long) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_notification_method_invalid_type(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.NotFound, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, type='random') - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_notification_method_address_exceeds_max_length(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - new_address_long = "x" * ( - constants.MAX_NOTIFICATION_METHOD_ADDRESS_LENGTH + 1) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, address=new_address_long) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_email_notification_method_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, period=60) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_webhook_notification_method_to_email_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, type='EMAIL') - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_webhook_notification_method_to_pagerduty_with_nonzero_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, type='PAGERDUTY') - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_notification_method_with_non_int_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, period='zero') - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_patch_webhook_notification_method_with_invalid_period(self): - name = data_utils.rand_name('notification-') - notification = helpers.create_notification(name=name, - type='WEBHOOK', - address='http://localhost/test01', - period=60) - resp, response_body = self.monasca_client.create_notifications( - notification) - id = response_body['id'] - self.assertEqual(201, resp.status) - self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), - self.monasca_client.patch_notification_method, id, period=5) - resp, response_body = \ - self.monasca_client.delete_notification_method(id) - self.assertEqual(204, resp.status) diff --git a/monasca_tempest_tests/tests/api/test_read_only_role.py b/monasca_tempest_tests/tests/api/test_read_only_role.py deleted file mode 100644 index 0a1f127f9..000000000 --- a/monasca_tempest_tests/tests/api/test_read_only_role.py +++ /dev/null @@ -1,184 +0,0 @@ -# (C) Copyright 2016 Hewlett Packard Enterprise Development LP -# 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 time - -from tempest.lib import decorators -from tempest.lib import exceptions - -from monasca_tempest_tests import clients -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import helpers - - -class TestReadOnlyRole(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestReadOnlyRole, cls).resource_setup() - credentials = cls.cred_provider.get_creds_by_roles( - ['monasca-read-only-user']).credentials - cls.os = clients.Manager(credentials=credentials) - cls.monasca_client = cls.os.monasca_client - - @classmethod - def resource_cleanup(cls): - super(TestReadOnlyRole, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_list_alarms_success(self): - resp, response_body = self.monasca_client.list_alarms() - # - # Validate the call succeeds with empty result (we didn't - # create any alarms) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/alarms')) - - @decorators.attr(type="gate") - def test_list_metrics_success(self): - resp, response_body = self.monasca_client.list_metrics() - # - # Validate the call succeeds with empty result (we didn't - # create any metrics) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/metrics')) - - @decorators.attr(type="gate") - def test_list_alarm_definition_success(self): - resp, response_body = self.monasca_client.list_alarm_definitions() - # - # Validate the call succeeds with empty result (we didn't - # create any alarm definitions) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/alarm-definitions')) - - @decorators.attr(type="gate") - def test_list_notification_methods_success(self): - resp, response_body = self.monasca_client.list_notification_methods() - # - # Validate the call succeeds with empty result (we didn't - # create any notifications) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/notification-methods')) - - @decorators.attr(type="gate") - def test_list_alarm_count_success(self): - resp, response_body = self.monasca_client.count_alarms() - # - # Validate the call succeeds with empty result (we didn't - # create any alarms to count) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, response_body['counts'][0][0]) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/alarms/count')) - - @decorators.attr(type="gate") - def test_list_alarm_state_history_success(self): - resp, response_body = self.monasca_client.list_alarms_state_history() - # - # Validate the call succeeds with empty result (we didn't - # create any alarms that have history) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith('/v2.0/alarms/state-history')) - - @decorators.attr(type="gate") - def test_list_dimension_values_success(self): - parms = '?dimension_name=foo' - resp, response_body = self.monasca_client.list_dimension_values(parms) - # - # Validate the call succeeds with empty result (we didn't - # create any metrics/dimensions) - # - url = '/v2.0/metrics/dimensions/names/values?dimension_name=foo' - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith(url)) - - @decorators.attr(type="gate") - def test_list_dimension_names_success(self): - resp, response_body = self.monasca_client.list_dimension_names() - # - # Validate the call succeeds with empty result (we didn't - # create any metrics/dimensions) - # - url = '/v2.0/metrics/dimensions/names' - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue(response_body['links'][0]['href'].endswith(url)) - - @decorators.attr(type="gate") - def test_list_measurements_success(self): - start_timestamp = int(time.time() * 1000) - start_time = str(helpers.timestamp_to_iso(start_timestamp)) - parms = '?name=foo&start_time=' + start_time - resp, response_body = self.monasca_client.list_measurements(parms) - # - # Validate the call succeeds with empty result (we didn't - # create any metrics to get measurements for) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue('/v2.0/metrics/measurements' in response_body['links'][0]['href']) - - @decorators.attr(type="gate") - def test_list_statistics_success(self): - start_timestamp = int(time.time() * 1000) - start_time = str(helpers.timestamp_to_iso(start_timestamp)) - query_parms = '?name=foo&statistics=avg&start_time=' + start_time - resp, response_body = self.monasca_client.list_statistics( - query_parms) - # - # Validate the call succeeds with empty result (we didn't - # create any metrics to get statistics for) - # - self.assertEqual(200, resp.status) - self.assertEqual(0, len(response_body['elements'])) - self.assertTrue('/v2.0/metrics/statistics' in response_body['links'][0]['href']) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_delete_alarms_fails(self): - self.assertRaises(exceptions.Unauthorized, - self.monasca_client.delete_alarm, "foo") - - @decorators.attr(type='gate') - @decorators.attr(type=['negative']) - def test_create_metric_fails(self): - self.assertRaises(exceptions.Unauthorized, - self.monasca_client.create_metrics, - None) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_alarm_definition_fails(self): - self.assertRaises(exceptions.Unauthorized, - self.monasca_client.create_alarm_definitions, - None) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_create_notification_fails(self): - notif = helpers.create_notification() - self.assertRaises(exceptions.Unauthorized, - self.monasca_client.create_notifications, - notif) diff --git a/monasca_tempest_tests/tests/api/test_statistics.py b/monasca_tempest_tests/tests/api/test_statistics.py deleted file mode 100644 index 47f979dcb..000000000 --- a/monasca_tempest_tests/tests/api/test_statistics.py +++ /dev/null @@ -1,510 +0,0 @@ -# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP -# (C) Copyright 2017-2018 SUSE LLC -# -# 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 time - -import six.moves.urllib.parse as urlparse - -from monasca_tempest_tests.tests.api import base -from monasca_tempest_tests.tests.api import constants -from monasca_tempest_tests.tests.api import helpers -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions -from urllib import urlencode - -NUM_MEASUREMENTS = 100 -MIN_REQUIRED_MEASUREMENTS = 2 -WAIT_TIME = 30 - - -class TestStatistics(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestStatistics, cls).resource_setup() - name = data_utils.rand_name('name') - key = data_utils.rand_name('key') - value1 = data_utils.rand_name('value1') - value2 = data_utils.rand_name('value2') - cls._test_name = name - cls._test_key = key - cls._test_value1 = value1 - cls._start_timestamp = int(time.time() * 1000) - metrics = [ - helpers.create_metric(name=name, - dimensions={key: value1}, - timestamp=cls._start_timestamp, - value=1.23), - helpers.create_metric(name=name, - dimensions={key: value2}, - timestamp=cls._start_timestamp + 1000, - value=4.56) - ] - cls.metric_values = [m['value'] for m in metrics] - cls.monasca_client.create_metrics(metrics) - start_time_iso = helpers.timestamp_to_iso(cls._start_timestamp) - query_param = '?name=' + str(name) + '&start_time=' + \ - start_time_iso + '&merge_metrics=true' + '&end_time=' + \ - helpers.timestamp_to_iso(cls._start_timestamp + 1000 * 2) - start_time_iso = helpers.timestamp_to_iso(cls._start_timestamp) - cls._start_time_iso = start_time_iso - - num_measurements = 0 - for i in range(constants.MAX_RETRIES): - resp, response_body = cls.monasca_client.\ - list_measurements(query_param) - elements = response_body['elements'] - if len(elements) > 0: - num_measurements = len(elements[0]['measurements']) - if num_measurements >= MIN_REQUIRED_MEASUREMENTS: - break - time.sleep(constants.RETRY_WAIT_SECS) - - if num_measurements < MIN_REQUIRED_MEASUREMENTS: - assert False, "Required {} measurements, found {}".format(MIN_REQUIRED_MEASUREMENTS, num_measurements) - - cls._end_timestamp = cls._start_timestamp + 3000 - cls._end_time_iso = helpers.timestamp_to_iso(cls._end_timestamp) - - name2 = data_utils.rand_name("group-by") - cls._group_by_metric_name = name2 - cls._group_by_end_time_iso = helpers.timestamp_to_iso(cls._start_timestamp + 4000) - - group_by_metrics = [ - helpers.create_metric(name=name2, dimensions={'key1': 'value1', 'key2': 'value5', 'key3': 'value7'}, - timestamp=cls._start_timestamp + 1, value=2), - helpers.create_metric(name=name2, dimensions={'key1': 'value2', 'key2': 'value5', 'key3': 'value7'}, - timestamp=cls._start_timestamp + 1001, value=3), - helpers.create_metric(name=name2, dimensions={'key1': 'value3', 'key2': 'value6', 'key3': 'value7'}, - timestamp=cls._start_timestamp + 2001, value=5), - helpers.create_metric(name=name2, dimensions={'key1': 'value4', 'key2': 'value6', 'key3': 'value8'}, - timestamp=cls._start_timestamp + 3001, value=7), - ] - - cls.monasca_client.create_metrics(group_by_metrics) - query_param = '?name=' + str(name2) + \ - '&start_time=' + start_time_iso + \ - '&merge_metrics=true' + \ - '&end_time=' + cls._group_by_end_time_iso - - num_measurements = 0 - for i in range(constants.MAX_RETRIES): - resp, response_body = cls.monasca_client. \ - list_measurements(query_param) - elements = response_body['elements'] - if len(elements) > 0: - num_measurements = len(elements[0]['measurements']) - if num_measurements >= len(group_by_metrics): - break - time.sleep(constants.RETRY_WAIT_SECS) - - if num_measurements < len(group_by_metrics): - assert False, "Required {} measurements, found {}".format(len(group_by_metrics), - response_body) - - @classmethod - def resource_cleanup(cls): - super(TestStatistics, cls).resource_cleanup() - - @decorators.attr(type="gate") - def test_list_statistics(self): - self._test_list_statistic(with_end_time=True) - - @decorators.attr(type="gate") - def test_list_statistics_with_no_end_time(self): - self._test_list_statistic(with_end_time=False) - - def _test_list_statistic(self, with_end_time=True): - query_parms = '?name=' + str(self._test_name) + \ - '&statistics=' + urlparse.quote('avg,sum,min,max,count') + \ - '&start_time=' + str(self._start_time_iso) + \ - '&merge_metrics=true' + '&period=100000' - if with_end_time is True: - query_parms += '&end_time=' + str(self._end_time_iso) - - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - element = response_body['elements'][0] - self._verify_element(element) - column = element['columns'] - num_statistics_method = 5 - statistics = element['statistics'][0] - self._verify_column_and_statistics( - column, num_statistics_method, statistics, self.metric_values) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_no_name(self): - query_parms = '?merge_metrics=true&statistics=avg&start_time=' + \ - str(self._start_time_iso) + '&end_time=' + \ - str(self._end_time_iso) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_no_statistics(self): - query_parms = '?name=' + str(self._test_name) + '&start_time=' + str( - self._start_time_iso) + '&end_time=' + str(self._end_time_iso) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_no_start_time(self): - query_parms = '?name=' + str(self._test_name) + '&statistics=avg' - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_invalid_statistics(self): - query_parms = '?name=' + str(self._test_name) + '&statistics=abc' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._end_time_iso) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - def test_list_statistics_with_dimensions(self): - query_parms = '?name=' + str(self._test_name) + '&statistics=avg' \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._end_time_iso) + \ - '&dimensions=' + str(self._test_key) + ':' + \ - str(self._test_value1) + '&period=100000' - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - dimensions = response_body['elements'][0]['dimensions'] - self.assertEqual(dimensions[self._test_key], self._test_value1) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_end_time_equals_start_time(self): - query_parms = '?name=' + str(self._test_name) + \ - '&merge_metrics=true&statistics=avg&' \ - 'start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._start_time_iso) + \ - '&period=100000' - self.assertRaises(exceptions.BadRequest, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - def test_list_statistics_with_period(self): - query_parms = '?name=' + str(self._test_name) + \ - '&merge_metrics=true&statistics=avg&' \ - 'start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._end_time_iso) + \ - '&period=1' - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - time_diff = self._end_timestamp - self._start_timestamp - len_statistics = len(response_body['elements'][0]['statistics']) - self.assertEqual(time_diff / 1000, len_statistics) - - @decorators.attr(type="gate") - def test_list_statistics_with_offset_limit(self): - start_timestamp = int(time.time() * 1000) - name = data_utils.rand_name() - metric = [ - helpers.create_metric(name=name, timestamp=start_timestamp + 1, - dimensions={'key1': 'value-1', - 'key2': 'value-1'}, - value=1), - helpers.create_metric(name=name, timestamp=start_timestamp + 1001, - dimensions={'key1': 'value-2', - 'key2': 'value-2'}, - value=2), - helpers.create_metric(name=name, timestamp=start_timestamp + 2001, - dimensions={'key1': 'value-3', - 'key2': 'value-3'}, - value=3), - helpers.create_metric(name=name, timestamp=start_timestamp + 3001, - dimensions={'key1': 'value-4', - 'key2': 'value-4'}, - value=4) - ] - - num_metrics = len(metric) - self.monasca_client.create_metrics(metric) - query_parms = '?name=' + name - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.list_metrics(query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - if elements and len(elements) == num_metrics: - break - else: - time.sleep(constants.RETRY_WAIT_SECS) - self._check_timeout(i, constants.MAX_RETRIES, elements, num_metrics) - - start_time = helpers.timestamp_to_iso(start_timestamp) - end_timestamp = start_timestamp + 4001 - end_time = helpers.timestamp_to_iso(end_timestamp) - query_parms = '?name=' + name + '&merge_metrics=true&statistics=avg' \ - + '&start_time=' + str(start_time) + '&end_time=' + \ - str(end_time) + '&period=1' - resp, body = self.monasca_client.list_statistics(query_parms) - self.assertEqual(200, resp.status) - elements = body['elements'][0]['statistics'] - first_element = elements[0] - - query_parms = '?name=' + name + '&merge_metrics=true&statistics=avg'\ - + '&start_time=' + str(start_time) + '&end_time=' + \ - str(end_time) + '&period=1' + '&limit=' + str(num_metrics) - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'][0]['statistics'] - self.assertEqual(num_metrics, len(elements)) - self.assertEqual(first_element, elements[0]) - - for limit in range(1, num_metrics): - start_index = 0 - params = [('name', name), - ('merge_metrics', 'true'), - ('statistics', 'avg'), - ('start_time', str(start_time)), - ('end_time', str(end_time)), - ('period', 1), - ('limit', limit)] - offset = None - while True: - num_expected_elements = limit - if (num_expected_elements + start_index) > num_metrics: - num_expected_elements = num_metrics - start_index - - these_params = list(params) - # If not the first call, use the offset returned by the last call - if offset: - these_params.extend([('offset', str(offset))]) - query_parms = '?' + urlencode(these_params) - resp, response_body = self.monasca_client.list_statistics(query_parms) - self.assertEqual(200, resp.status) - if not response_body['elements']: - self.fail("No metrics returned") - if not response_body['elements'][0]['statistics']: - self.fail("No statistics returned") - new_elements = response_body['elements'][0]['statistics'] - - self.assertEqual(num_expected_elements, len(new_elements)) - expected_elements = elements[start_index:start_index + limit] - self.assertEqual(expected_elements, new_elements) - start_index += num_expected_elements - if start_index >= num_metrics: - break - # Get the next set - offset = self._get_offset(response_body) - - @decorators.attr(type="gate") - def test_list_statistics_with_group_by_one(self): - query_parms = '?name=' + self._group_by_metric_name + \ - '&group_by=key2' + \ - '&statistics=max,avg,min' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._group_by_end_time_iso) - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 2) - for statistics in elements: - self.assertEqual(1, len(statistics['dimensions'].keys())) - self.assertEqual([u'key2'], statistics['dimensions'].keys()) - - @decorators.attr(type="gate") - def test_list_statistics_with_group_by_multiple(self): - query_parms = '?name=' + self._group_by_metric_name + \ - '&group_by=key2,key3' + \ - '&statistics=max,avg,min' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._group_by_end_time_iso) - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 3) - for statistics in elements: - self.assertEqual(2, len(statistics['dimensions'].keys())) - self.assertEqual({u'key2', u'key3'}, set(statistics['dimensions'].keys())) - - @decorators.attr(type="gate") - def test_list_statistics_with_group_by_all(self): - query_parms = '?name=' + self._group_by_metric_name + \ - '&group_by=*' + \ - '&statistics=max,avg,min' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._group_by_end_time_iso) - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - elements = response_body['elements'] - self.assertEqual(len(elements), 4) - - @decorators.attr(type="gate") - def test_list_statistics_with_group_by_offset_limit(self): - query_parms = '?name=' + str(self._group_by_metric_name) + \ - '&group_by=key2' + \ - '&statistics=avg,max' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._group_by_end_time_iso) + \ - '&period=1' - resp, response_body = self.monasca_client.list_statistics(query_parms) - self.assertEqual(200, resp.status) - all_expected_elements = response_body['elements'] - - for limit in range(1, 4): - offset = None - for i in range(4 - limit): - query_parms = '?name=' + str(self._group_by_metric_name) + \ - '&group_by=key2' + \ - '&statistics=avg,max' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._group_by_end_time_iso) + \ - '&period=1' + \ - '&limit=' + str(limit) - if i > 0: - offset = self._get_offset(response_body) - query_parms += "&offset=" + offset - - expected_elements = helpers.get_expected_elements_inner_offset_limit( - all_expected_elements, - offset, - limit, - 'statistics') - - resp, response_body = self.monasca_client.list_statistics(query_parms) - self.assertEqual(200, resp.status) - self.assertEqual(expected_elements, response_body['elements']) - - @decorators.attr(type="gate") - def test_list_statistics_with_long_start_time(self): - query_parms = '?name=' + str(self._test_name) + \ - '&statistics=' + urlparse.quote('avg,sum,min,max,count') + \ - '&start_time=' + "2017-01-01T00:00:00.00Z" + \ - '&end_time=' + str(self._end_time_iso) + \ - '&merge_metrics=true' + '&period=100000' - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - self.assertTrue(set(['links', 'elements']) == set(response_body)) - element = response_body['elements'][0] - self._verify_element(element) - column = element['columns'] - num_statistics_method = 5 - statistics = element['statistics'][0] - self._verify_column_and_statistics( - column, num_statistics_method, statistics, self.metric_values) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_no_merge_metrics(self): - key = data_utils.rand_name('key') - value = data_utils.rand_name('value') - metric3 = helpers.create_metric( - name=self._test_name, - dimensions={key: value}, - timestamp=self._start_timestamp + 2000) - self.monasca_client.create_metrics(metric3) - query_param = '?name=' + str(self._test_name) + '&start_time=' + \ - self._start_time_iso + '&end_time=' + helpers.\ - timestamp_to_iso(self._start_timestamp + 1000 * 4) + \ - '&merge_metrics=True' - - for i in range(constants.MAX_RETRIES): - resp, response_body = self.monasca_client.\ - list_measurements(query_param) - elements = response_body['elements'] - for element in elements: - if str(element['name']) == self._test_name and len( - element['measurements']) == 3: - end_time_iso = helpers.timestamp_to_iso( - self._start_timestamp + 1000 * 4) - query_parms = '?name=' + str(self._test_name) + \ - '&statistics=avg' + '&start_time=' + \ - str(self._start_time_iso) + '&end_time=' +\ - str(end_time_iso) + '&period=100000' - self.assertRaises(exceptions.Conflict, - self.monasca_client.list_statistics, - query_parms) - return - time.sleep(constants.RETRY_WAIT_SECS) - self._check_timeout(i, constants.MAX_RETRIES, elements, 3) - - @decorators.attr(type="gate") - @decorators.attr(type=['negative']) - def test_list_statistics_with_name_exceeds_max_length(self): - long_name = "x" * (constants.MAX_LIST_STATISTICS_NAME_LENGTH + 1) - query_parms = '?name=' + str(long_name) + '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._end_time_iso) - self.assertRaises(exceptions.UnprocessableEntity, - self.monasca_client.list_statistics, query_parms) - - @decorators.attr(type="gate") - def test_list_statistics_response_body_statistic_result_type(self): - query_parms = '?name=' + str(self._test_name) + '&period=100000' + \ - '&statistics=avg' + '&merge_metrics=true' + \ - '&start_time=' + str(self._start_time_iso) + \ - '&end_time=' + str(self._end_time_iso) - resp, response_body = self.monasca_client.list_statistics( - query_parms) - self.assertEqual(200, resp.status) - element = response_body['elements'][0] - statistic = element['statistics'] - statistic_result_type = type(statistic[0][1]) - self.assertEqual(statistic_result_type, float) - - def _verify_element(self, element): - self.assertTrue(set(['id', 'name', 'dimensions', 'columns', - 'statistics']) == set(element)) - self.assertTrue(type(element['id']) is unicode) - self.assertTrue(element['id'] is not None) - self.assertTrue(type(element['name']) is unicode) - self.assertTrue(type(element['dimensions']) is dict) - self.assertEqual(len(element['dimensions']), 0) - self.assertTrue(type(element['columns']) is list) - self.assertTrue(type(element['statistics']) is list) - self.assertEqual(element['name'], self._test_name) - - def _verify_column_and_statistics( - self, column, num_statistics_method, statistics, values): - self.assertTrue(type(column) is list) - self.assertTrue(type(statistics) is list) - self.assertEqual(len(column), num_statistics_method + 1) - self.assertEqual(column[0], 'timestamp') - for i, method in enumerate(column): - if method == 'avg': - self.assertAlmostEqual(statistics[i], float(sum(values) / len(values))) - elif method == 'max': - self.assertEqual(statistics[i], max(values)) - elif method == 'min': - self.assertEqual(statistics[i], min(values)) - elif method == 'sum': - self.assertAlmostEqual(statistics[i], sum(values)) - elif method == 'count': - self.assertEqual(statistics[i], len(values)) - - def _check_timeout(self, timer, max_retries, elements, - expect_num_elements): - if timer == max_retries - 1: - error_msg = ("Failed: timeout on waiting for metrics: {} elements " - "are needed. Current number of elements = {}").\ - format(expect_num_elements, len(elements)) - raise self.fail(error_msg) diff --git a/monasca_tempest_tests/tests/api/test_versions.py b/monasca_tempest_tests/tests/api/test_versions.py deleted file mode 100644 index 00e2e21c4..000000000 --- a/monasca_tempest_tests/tests/api/test_versions.py +++ /dev/null @@ -1,50 +0,0 @@ -# (C) Copyright 2015,2017 Hewlett Packard Enterprise Development Company LP -# -# 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 datetime - -from oslo_serialization import jsonutils as json - -from monasca_tempest_tests.tests.api import base -from tempest.lib import decorators - - -class TestVersions(base.BaseMonascaTest): - - @classmethod - def resource_setup(cls): - super(TestVersions, cls).resource_setup() - - @decorators.attr(type='gate') - def test_get_version(self): - resp, response_body = self.monasca_client.get_version() - self.assertEqual(resp.status, 200) - response_body = json.loads(response_body) - - self.assertIsInstance(response_body, dict) - version = response_body - self.assertTrue(set(['id', 'links', 'status', 'updated']) == - set(version)) - self.assertEqual(version['id'], u'v2.0') - self.assertEqual(version['status'], u'CURRENT') - date_object = datetime.datetime.strptime(version['updated'], - "%Y-%m-%dT%H:%M:%S.%fZ") - self.assertIsInstance(date_object, datetime.datetime) - links = response_body['links'] - self.assertIsInstance(links, list) - link = links[0] - self.assertTrue(set(['rel', 'href']) == - set(link)) - self.assertEqual(link['rel'], u'self') - self.assertTrue(link['href'].endswith('/v2.0')) diff --git a/playbooks/legacy/monasca-tempest-base/run.yaml b/playbooks/legacy/monasca-tempest-base/run.yaml index a6f355488..cfffbd17c 100644 --- a/playbooks/legacy/monasca-tempest-base/run.yaml +++ b/playbooks/legacy/monasca-tempest-base/run.yaml @@ -34,7 +34,7 @@ MONASCA_API_IMPLEMENTATION_LANG="{{ api_lang }}" MONASCA_PERSISTER_IMPLEMENTATION_LANG="{{ persister_lang }}" MONASCA_METRICS_DB="{{ tsdb }}" - + TEMPEST_PLUGINS+='/opt/stack/new/monasca-tempest-plugin' EOF executable: /bin/bash chdir: '{{ ansible_user_dir }}/workspace' @@ -50,6 +50,8 @@ export DEVSTACK_GATE_NEUTRON=1 export DEVSTACK_GATE_EXERCISES=0 + export DEVSTACK_GATE_TEMPEST=1 + export DEVSTACK_GATE_TEMPEST_REGEX="monasca_tempest_tests.tests.api" if [ "{{ database }}" == "postgresql" ]; then export DEVSTACK_GATE_POSTGRES=1 @@ -67,15 +69,11 @@ export PROJECTS="openstack/python-monascaclient $PROJECTS" export PROJECTS="openstack/monasca-grafana-datasource $PROJECTS" export PROJECTS="openstack/monasca-ui $PROJECTS" - - function pre_test_hook { - source $BASE/new/monasca-api/monasca_tempest_tests/contrib/gate_hook.sh - } - export -f pre_test_hook + export PROJECTS="openstack/monasca-tempest-plugin $PROJECTS" function post_test_hook { # Configure and run tempest on monasca-api installation - source $BASE/new/monasca-api/monasca_tempest_tests/contrib/post_test_hook.sh + source $BASE/new/monasca-api/contrib/post_test_hook.sh } export -f post_test_hook diff --git a/setup.cfg b/setup.cfg index c916f2c42..34bdb9f32 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,7 +20,6 @@ classifier = [files] packages = monasca_api - monasca_tempest_tests data_files = /etc/monasca = @@ -31,9 +30,6 @@ data_files = console_scripts = monasca-api = monasca_api.api.server:launch -tempest.test_plugins = - monasca_tests = monasca_tempest_tests.plugin:MonascaTempestPlugin - oslo.config.opts = monasca_api = monasca_api.conf:list_opts diff --git a/tox.ini b/tox.ini index a55f1ff1e..a38b102b9 100644 --- a/tox.ini +++ b/tox.ini @@ -51,7 +51,7 @@ skip_install = True usedevelop = False commands = {[testenv]commands} - flake8 monasca_api monasca_tempest_tests + flake8 monasca_api [testenv:bandit] skip_install = True @@ -59,8 +59,6 @@ usedevelop = False commands = # B101(assert_ussed) - API uses asserts because of performance reasons bandit -r monasca_api -n5 -s B101 -x monasca_api/tests - # B101(assert_ussed) - asserts in test layers seems appropriate - bandit -r monasca_tempest_tests -n5 -s B101 [testenv:bashate] skip_install = True