Merge "Add Monasca Tempest Tests"
This commit is contained in:
commit
12fbdf83cd
@ -2,7 +2,7 @@
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover monasca_api $LISTOPT $IDOPTION
|
||||
${PYTHON:-python} -m subunit.run discover -t . ./monasca_api/tests $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
|
102
monasca_tempest_tests/README.md
Normal file
102
monasca_tempest_tests/README.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Introduction
|
||||
The Monasca Tempest Tests use the [OpenStack Tempest Plugin Interface](http://docs.openstack.org/developer/tempest/plugin.html). This README describes how to configure and run them using a variety of methods.
|
||||
Currently monasca-vagrant is used to run tests. This document will be updated when switch the environment to DevStack.
|
||||
|
||||
# Configuring to run the Monasca Tempest Tests
|
||||
1. Clone the OpenStack Tempest repo, and cd to it.
|
||||
```
|
||||
git clone https://github.com/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
|
||||
pip install nose
|
||||
```
|
||||
4. Create ```etc/tempest.conf``` and ```etc/logging.conf``` in the Tempest root dir. I believe the file ```etc/tempest.conf.sample``` can be copied to ```etc/tempest.conf```. Similarly for ```logging.conf```. Add the following sections to ```tempest.conf``` for testing using the monasca-vagrant environment.
|
||||
```
|
||||
[identity]
|
||||
|
||||
username = mini-mon
|
||||
password = password
|
||||
tenant_name = mini-mon
|
||||
domain_name = default
|
||||
admin_username = admin
|
||||
admin_password = admin
|
||||
admin_domain_name = default
|
||||
admin_tenant_name = admin
|
||||
alt_username = mini-mon
|
||||
alt_password = password
|
||||
alt_tenant_name = mini-mon
|
||||
use_ssl = False
|
||||
auth_version = v3
|
||||
uri = http://192.168.10.5:5000/v2.0/
|
||||
uri_v3 = http://192.168.10.5:35357/v3/
|
||||
|
||||
[auth]
|
||||
|
||||
allow_tenant_isolation = true
|
||||
tempest_roles = monasca-user
|
||||
```
|
||||
5. Clone the monasca-api repo.
|
||||
6. Install the monasca-api in your venv, which will also register
|
||||
the Monasca Tempest Plugin as, monasca_tests.
|
||||
```
|
||||
python setup.py install
|
||||
```
|
||||
See the [OpenStack Tempest Plugin Interface](http://docs.openstack.org/developer/tempest/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](http://docs.openstack.org/developer/os-testr/)
|
||||
3. [PyCharm]([Os-testr](https://www.jetbrains.com/pycharm/)
|
||||
|
||||
## 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. In the Tempest root dir, create a list of the Monasca Tempest Tests in a file.
|
||||
```
|
||||
testr list-tests monasca_tempest_tests > monasca_tempest_tests
|
||||
```
|
||||
2. 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 from the CLI using os-testr (no file necessary)
|
||||
[Os-testr](http://docs.openstack.org/developer/os-testr/) is a test wrapper that can be used to run the Monasca Tempest tests.
|
||||
In the Tempest root dir:
|
||||
```
|
||||
ostestr --regex monasca_tempest_tests
|
||||
```
|
||||
## Running/Debugging the Monasca Tempest Tests in PyCharm
|
||||
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.
|
||||
|
||||
# References
|
||||
This section provides a few additional references that might be useful:
|
||||
* [Tempest - The OpenStack Integration Test Suite](http://docs.openstack.org/developer/tempest/overview.html#quickstart)
|
||||
* [Tempest Configuration Guide](https://github.com/openstack/tempest/blob/master/doc/source/configuration.rst#id1)
|
||||
* [OpenStack Tempest Plugin Interface](http://docs.openstack.org/developer/tempest/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.
|
0
monasca_tempest_tests/__init__.py
Normal file
0
monasca_tempest_tests/__init__.py
Normal file
23
monasca_tempest_tests/clients.py
Normal file
23
monasca_tempest_tests/clients.py
Normal file
@ -0,0 +1,23 @@
|
||||
# (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 tempest import clients
|
||||
|
||||
from monasca_tempest_tests.services import monasca_client
|
||||
|
||||
|
||||
class Manager(clients.Manager):
|
||||
def __init__(self, credentials=None, service=None):
|
||||
super(Manager, self).__init__(credentials, service)
|
||||
self.monasca_client = monasca_client.MonascaClient(self.auth_provider)
|
45
monasca_tempest_tests/config.py
Normal file
45
monasca_tempest_tests/config.py
Normal file
@ -0,0 +1,45 @@
|
||||
# (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_available_group = cfg.OptGroup(name="service_available",
|
||||
title="Available OpenStack Services")
|
||||
|
||||
ServiceAvailableGroup = [
|
||||
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.")
|
||||
]
|
40
monasca_tempest_tests/plugin.py
Normal file
40
monasca_tempest_tests/plugin.py
Normal file
@ -0,0 +1,40 @@
|
||||
# (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 import config
|
||||
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):
|
||||
config.register_opt_group(
|
||||
conf, config_monitoring.service_available_group,
|
||||
config_monitoring.ServiceAvailableGroup)
|
||||
config.register_opt_group(conf, config_monitoring.monitoring_group,
|
||||
config_monitoring.MonitoringGroup)
|
||||
|
||||
def get_opt_lists(self):
|
||||
return [(config_monitoring.monitoring_group.name,
|
||||
config_monitoring.MonitoringGroup)]
|
0
monasca_tempest_tests/services/__init__.py
Normal file
0
monasca_tempest_tests/services/__init__.py
Normal file
275
monasca_tempest_tests/services/monasca_client.py
Normal file
275
monasca_tempest_tests/services/monasca_client.py
Normal file
@ -0,0 +1,275 @@
|
||||
# (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_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):
|
||||
uri = 'metrics'
|
||||
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_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):
|
||||
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
|
||||
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=None,
|
||||
type=None,
|
||||
address=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
|
||||
resp, response_body = self.put(uri, json.dumps(request_body))
|
||||
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=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 = {}
|
||||
request_body['name'] = name
|
||||
request_body['expression'] = expression
|
||||
|
||||
if description is not None:
|
||||
request_body['description'] = description
|
||||
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.iteritems():
|
||||
request_body[key] = value
|
||||
|
||||
resp, response_body = self.patch(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.iteritems():
|
||||
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.iteritems():
|
||||
request_body[key] = value
|
||||
|
||||
resp, response_body = self.patch(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.iteritems():
|
||||
request_body[key] = value
|
||||
|
||||
resp, response_body = self.patch(uri, json.dumps(request_body))
|
||||
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)
|
0
monasca_tempest_tests/tests/__init__.py
Normal file
0
monasca_tempest_tests/tests/__init__.py
Normal file
0
monasca_tempest_tests/tests/api/__init__.py
Normal file
0
monasca_tempest_tests/tests/api/__init__.py
Normal file
52
monasca_tempest_tests/tests/api/base.py
Normal file
52
monasca_tempest_tests/tests/api/base.py
Normal file
@ -0,0 +1,52 @@
|
||||
# (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 tempest import config
|
||||
import tempest.test
|
||||
from tempest_lib import exceptions
|
||||
|
||||
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()
|
||||
cls.os = clients.Manager()
|
||||
cls.monasca_client = cls.os.monasca_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()
|
||||
elements = response_body['elements']
|
||||
for definition in elements:
|
||||
id = definition['id']
|
||||
resp, response_body = cls.monasca_client. \
|
||||
delete_alarm_definition(id)
|
37
monasca_tempest_tests/tests/api/constants.py
Normal file
37
monasca_tempest_tests/tests/api/constants.py
Normal file
@ -0,0 +1,37 @@
|
||||
# (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.
|
||||
|
||||
MAX_METRIC_NAME_LENGTH = 255
|
||||
MAX_DIMENSION_KEY_LENGTH = 255
|
||||
MAX_DIMENSION_VALUE_LENGTH = 255
|
||||
INVALID_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 = 100
|
||||
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
|
77
monasca_tempest_tests/tests/api/helpers.py
Normal file
77
monasca_tempest_tests/tests/api/helpers.py
Normal file
@ -0,0 +1,77 @@
|
||||
# (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 time
|
||||
|
||||
from tempest.common.utils import data_utils
|
||||
|
||||
|
||||
def create_metric(name='name-1',
|
||||
dimensions={
|
||||
'key-1': 'value-1',
|
||||
'key-2': 'value-2'
|
||||
},
|
||||
timestamp=time.time() * 1000,
|
||||
value=0.0):
|
||||
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
|
||||
if value is not None:
|
||||
metric['value'] = value
|
||||
return metric
|
||||
|
||||
|
||||
def create_notification(name=data_utils.rand_name('notification-'),
|
||||
type='EMAIL',
|
||||
address='john.doe@domain.com'):
|
||||
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
|
||||
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
|
483
monasca_tempest_tests/tests/api/test_alarm_definitions.py
Normal file
483
monasca_tempest_tests/tests/api/test_alarm_definitions.py
Normal file
@ -0,0 +1,483 @@
|
||||
# (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 monasca_tempest_tests.tests.api import base
|
||||
from monasca_tempest_tests.tests.api import helpers
|
||||
from tempest.common.utils import data_utils
|
||||
from tempest import test
|
||||
from tempest_lib import exceptions
|
||||
|
||||
NUM_ALARM_DEFINITIONS = 2
|
||||
|
||||
|
||||
class TestAlarmDefinitions(base.BaseMonascaTest):
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestAlarmDefinitions, cls).resource_setup()
|
||||
cls.rule = {'expression': 'mem_total_mb > 0'}
|
||||
for i in range(NUM_ALARM_DEFINITIONS):
|
||||
alarm_definition = helpers.create_alarm_definition(
|
||||
name='alarm-definition-' + str(i),
|
||||
description='alarm definition description',
|
||||
expression='avg(cpu_utilization{service=compute}) >= 1000')
|
||||
cls.monasca_client.create_alarm_definitions(alarm_definition)
|
||||
|
||||
@classmethod
|
||||
def create_alarm_definition(cls):
|
||||
# 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)
|
||||
return alarm_definition
|
||||
|
||||
# Create
|
||||
@test.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)
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(name, response_body['name'])
|
||||
alarm_def_id = response_body['id']
|
||||
self.assertEqual(expression, response_body['expression'])
|
||||
|
||||
# Delete alarm and verify if deleted
|
||||
resp, response_body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_create_alarm_definition_with_notification(self):
|
||||
notification_name = data_utils.rand_name('notification-')
|
||||
notification_type = 'EMAIL'
|
||||
u_address = 'root@localhost'
|
||||
|
||||
resp, response_body = self.monasca_client.create_notification_method(
|
||||
notification_name, type=notification_type, address=u_address)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name, response_body['name'])
|
||||
notification_id = response_body['id']
|
||||
|
||||
# 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, body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(alarm_def_name, body['name'])
|
||||
alarm_def_id = body['id']
|
||||
self.assertEqual(expression, body['expression'])
|
||||
self.assertEqual(notification_id, body['ok_actions'][0])
|
||||
self.assertEqual(notification_id, body['alarm_actions'][0])
|
||||
self.assertEqual(notification_id, body['undetermined_actions'][0])
|
||||
|
||||
# Delete alarm definition and verify if deleted
|
||||
resp, body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
# Delete notification
|
||||
resp, body = self.monasca_client.delete_notification_method(
|
||||
notification_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.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, body = self.monasca_client.create_notification_method(
|
||||
notification_name1, type=notification_type1, address=address1)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name1, body['name'])
|
||||
notification_id1 = body['id']
|
||||
|
||||
resp, body = self.monasca_client.create_notification_method(
|
||||
notification_name2, type=notification_type2, address=address2)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name2, body['name'])
|
||||
notification_id2 = body['id']
|
||||
|
||||
# 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],
|
||||
severity="LOW")
|
||||
resp, body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(alarm_def_name, body['name'])
|
||||
alarm_def_id = body['id']
|
||||
self.assertEqual("mem_total_mb > 0", body['expression'])
|
||||
|
||||
# Delete alarm definition and validate if deleted
|
||||
resp, body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
# Delete notification 1
|
||||
resp, body = self.monasca_client.delete_notification_method(
|
||||
notification_id1)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
# Delete notification 2
|
||||
resp, body = self.monasca_client.delete_notification_method(
|
||||
notification_id2)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_create_alarm_definition_with_url_in_expression(self):
|
||||
notification_name = data_utils.rand_name('notification-')
|
||||
notification_type = 'EMAIL'
|
||||
u_address = 'root@localhost'
|
||||
|
||||
resp, body = self.monasca_client.create_notification_method(
|
||||
notification_name, type=notification_type, address=u_address)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name, body['name'])
|
||||
notification_id = body['id']
|
||||
|
||||
# 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,
|
||||
severity="LOW")
|
||||
resp, body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(alarm_def_name, body['name'])
|
||||
alarm_def_id = body['id']
|
||||
self.assertEqual("avg(mem_total_mb{url=https://www.google.com}) gt 0",
|
||||
body['expression'])
|
||||
|
||||
# Delete alarm and verify if deleted
|
||||
resp, body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
# Delete notification
|
||||
resp, body = self.monasca_client.delete_notification_method(
|
||||
notification_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_alarm_definition_with_special_chars_in_expression(self):
|
||||
notification_name = data_utils.rand_name('notification-')
|
||||
notification_type = 'EMAIL'
|
||||
u_address = 'root@localhost'
|
||||
|
||||
resp, body = self.monasca_client.create_notification_method(
|
||||
notification_name, type=notification_type, address=u_address)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name, body['name'])
|
||||
notification_id = body['id']
|
||||
|
||||
# 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,
|
||||
severity="LOW")
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_alarm_definitions,
|
||||
alarm_definition)
|
||||
|
||||
# List
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarm_definitions(self):
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions()
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
# Test list alarm definition response body
|
||||
self.assertTrue(isinstance(response_body, dict))
|
||||
self.assertTrue(set(['links', 'elements']) ==
|
||||
set(response_body))
|
||||
elements = response_body['elements']
|
||||
links = response_body['links']
|
||||
self.assertTrue(isinstance(links, list))
|
||||
link = links[0]
|
||||
self.assertTrue(set(['rel', 'href']) ==
|
||||
set(link))
|
||||
self.assertEqual(link['rel'], u'self')
|
||||
self.assertEqual(len(elements), NUM_ALARM_DEFINITIONS)
|
||||
for definition in elements:
|
||||
self.assertTrue(set(['id',
|
||||
'links',
|
||||
'name',
|
||||
'description',
|
||||
'expression',
|
||||
'match_by',
|
||||
'severity',
|
||||
'actions_enabled',
|
||||
'ok_actions',
|
||||
'alarm_actions',
|
||||
'undetermined_actions']) ==
|
||||
set(definition))
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarm_definitions_with_name(self):
|
||||
query_parms = '?name=name-1'
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarm_definitions_with_dimensions(self):
|
||||
query_parms = '?dimensions=key1:value1'
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarm_definitions_with_offset_limit(self):
|
||||
query_parms = '?offset=1&limit=2'
|
||||
resp, response_body = self.monasca_client.list_alarm_definitions(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
# Get
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_get_alarm_definition(self):
|
||||
alarm_definition = self.create_alarm_definition()
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
alarm_def_id = response_body['id']
|
||||
resp, response_body = self.monasca_client.get_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
# Test Get Alarm Definition Response Body
|
||||
self.assertTrue(isinstance(response_body, dict))
|
||||
self.assertTrue(set(['id', 'links', 'name', 'description',
|
||||
'expression', 'match_by', 'severity',
|
||||
'actions_enabled', 'alarm_actions',
|
||||
'ok_actions', 'undetermined_actions'
|
||||
]) ==
|
||||
set(response_body))
|
||||
links = response_body['links']
|
||||
self.assertTrue(isinstance(links, list))
|
||||
link = links[0]
|
||||
self.assertTrue(set(['rel', 'href']) ==
|
||||
set(link))
|
||||
self.assertEqual(link['rel'], u'self')
|
||||
|
||||
# Delete alarm and verify if deleted
|
||||
resp, response_body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
# Update
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_update_alarm_definition(self):
|
||||
alarm_definition = self.create_alarm_definition()
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
id = response_body['id']
|
||||
|
||||
# Update alarm definition
|
||||
updated_name = data_utils.rand_name('updated_name')
|
||||
updated_description = 'updated description'
|
||||
updated_expression = response_body['expression']
|
||||
resp, response_body = self.monasca_client.update_alarm_definition(
|
||||
id=id,
|
||||
name=updated_name,
|
||||
expression=updated_expression,
|
||||
description=updated_description,
|
||||
actions_enabled='true'
|
||||
)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
# Validate fields updated
|
||||
self.assertEqual(updated_name, response_body['name'])
|
||||
self.assertEqual(updated_expression, response_body['expression'])
|
||||
self.assertEqual(updated_description, response_body['description'])
|
||||
|
||||
# Get and validate details of alarm definition after update
|
||||
resp, response_body = self.monasca_client.get_alarm_definition(id)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(updated_name, response_body['name'])
|
||||
self.assertEqual(updated_description, response_body['description'])
|
||||
self.assertEqual(updated_expression, response_body['expression'])
|
||||
|
||||
# Test Updated alarm definition Response Body
|
||||
self.assertTrue(isinstance(response_body, dict))
|
||||
self.assertTrue(set(['id', 'links', 'name', 'description',
|
||||
'expression', 'match_by', 'severity',
|
||||
'actions_enabled', 'alarm_actions',
|
||||
'ok_actions', 'undetermined_actions'
|
||||
]) ==
|
||||
set(response_body))
|
||||
|
||||
links = response_body['links']
|
||||
self.assertTrue(isinstance(links, list))
|
||||
link = links[0]
|
||||
self.assertTrue(set(['rel', 'href']) ==
|
||||
set(link))
|
||||
self.assertEqual(link['rel'], u'self')
|
||||
|
||||
# Delete alarm definition
|
||||
resp, response_body = self.monasca_client.delete_alarm_definition(
|
||||
id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
# Validate alarm ID is not found
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition, id)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_update_notification_in_alarm_definition(self):
|
||||
notification_name = data_utils.rand_name('notification-')
|
||||
notification_type = 'EMAIL'
|
||||
u_address = 'root@localhost'
|
||||
|
||||
resp, body = self.monasca_client.create_notification_method(
|
||||
notification_name, type=notification_type, address=u_address)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(notification_name, body['name'])
|
||||
notification_id = body['id']
|
||||
|
||||
# Create an alarm definition
|
||||
alarm_definition = self.create_alarm_definition()
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
self.assertEqual(201, resp.status)
|
||||
alarm_def_id = response_body['id']
|
||||
expression = response_body['expression']
|
||||
|
||||
# Update alarm definition
|
||||
alarm_def_name = data_utils.rand_name('monitoring_alarm_update')
|
||||
resp, body = self.monasca_client.update_alarm_definition(
|
||||
alarm_def_id,
|
||||
name=alarm_def_name,
|
||||
expression=expression,
|
||||
actions_enabled='true',
|
||||
alarm_actions=notification_id,
|
||||
ok_actions=notification_id
|
||||
)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(alarm_def_name, body['name'])
|
||||
self.assertEqual(expression, body['expression'])
|
||||
self.assertEqual(notification_id, body['alarm_actions'][0])
|
||||
self.assertEqual(notification_id, body['ok_actions'][0])
|
||||
|
||||
# Get and verify details of an alarm after update
|
||||
resp, body = self.monasca_client.get_alarm_definition(alarm_def_id)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(alarm_def_name, body['name'])
|
||||
self.assertEqual(expression, body['expression'])
|
||||
|
||||
# Delete alarm and verify if deleted
|
||||
resp, _ = self.monasca_client.delete_alarm_definition(alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
||||
|
||||
# Delete notification
|
||||
resp, body = self.monasca_client.delete_notification_method(
|
||||
notification_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
# Patch
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_patch_alarm_definition(self):
|
||||
alarm_definition = self.create_alarm_definition()
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
id = response_body['id']
|
||||
|
||||
# Patch alarm definition
|
||||
patched_name = data_utils.rand_name('patched_name')
|
||||
resp, response_body = self.monasca_client.patch_alarm_definition(
|
||||
id=id,
|
||||
name=patched_name
|
||||
)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
# Validate fields updated
|
||||
self.assertEqual(patched_name, response_body['name'])
|
||||
|
||||
# Delete alarm definition
|
||||
resp, response_body = self.monasca_client.delete_alarm_definition(
|
||||
id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
# Validate alarm ID is not found
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
id)
|
||||
|
||||
# Delete
|
||||
@test.attr(type="gate")
|
||||
def test_create_and_delete_alarm_definition(self):
|
||||
alarm_definition = self.create_alarm_definition()
|
||||
resp, response_body = self.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
alarm_def_id = response_body['id']
|
||||
|
||||
# Delete alarm and verify if deleted
|
||||
resp, response_body = self.monasca_client.delete_alarm_definition(
|
||||
alarm_def_id)
|
||||
self.assertEqual(204, resp.status)
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.monasca_client.get_alarm_definition,
|
||||
alarm_def_id)
|
281
monasca_tempest_tests/tests/api/test_alarms.py
Normal file
281
monasca_tempest_tests/tests/api/test_alarms.py
Normal file
@ -0,0 +1,281 @@
|
||||
# (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.
|
||||
|
||||
# TODO(RMH): Update documentation. Get alarms returns alarm_definition, not
|
||||
# TODO(RMH): alarm_definition_id in response body
|
||||
import time
|
||||
|
||||
from monasca_tempest_tests.tests.api import base
|
||||
from monasca_tempest_tests.tests.api import helpers
|
||||
from tempest.common.utils import data_utils
|
||||
from tempest import test
|
||||
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()
|
||||
|
||||
@classmethod
|
||||
def create_alarms_for_test_alarms(cls):
|
||||
# create an alarm definition
|
||||
expression = "avg(name-1) > 0"
|
||||
name = data_utils.rand_name('name-1')
|
||||
alarm_definition = helpers.create_alarm_definition(
|
||||
name=name, expression=expression)
|
||||
resp, response_body = cls.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
# create some metrics
|
||||
for i in xrange(30):
|
||||
metric = helpers.create_metric()
|
||||
resp, response_body = cls.monasca_client.create_metrics(metric)
|
||||
time.sleep(1)
|
||||
resp, response_body = cls.monasca_client.list_alarms()
|
||||
elements = response_body['elements']
|
||||
if len(elements) > 0:
|
||||
break
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms(self):
|
||||
self.create_alarms_for_test_alarms()
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(set(['links', 'elements']) ==
|
||||
set(response_body))
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id',
|
||||
'links',
|
||||
'alarm_definition',
|
||||
'metrics',
|
||||
'state',
|
||||
'lifecycle_state',
|
||||
'link',
|
||||
'state_updated_timestamp',
|
||||
'updated_timestamp',
|
||||
'created_timestamp']) ==
|
||||
set(element))
|
||||
|
||||
for metric in element['metrics']:
|
||||
target_metric = helpers.create_metric()
|
||||
self.assertEqual(target_metric['name'], metric['name'])
|
||||
self.assertEqual(target_metric['dimensions'], metric['dimensions'])
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_alarm_definition_id(self):
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
alarm_definition_id = element['alarm_definition']['id']
|
||||
query_parms = '?alarm_definition_id=' + str(alarm_definition_id)
|
||||
resp, response_body = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
element_1 = response_body['elements'][0]
|
||||
self.assertEqual(element_1, element)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_metric_name(self):
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
metric_name = element['metrics'][0]['name']
|
||||
query_parms = '?metric_name=' + str(metric_name)
|
||||
resp, response_body = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
element_1 = response_body['elements'][0]
|
||||
self.assertEqual(element_1, element)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_metric_dimensions(self):
|
||||
query_parms = '?metric_dimensions=key-2:value-2,key-1:value-1'
|
||||
resp, response_body_1 = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_state(self):
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
len0 = len(response_body['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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_lifecycle_state(self):
|
||||
query_parms = '?lifecycle_state=None'
|
||||
resp, response_body = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_link(self):
|
||||
query_parms = '?link=None'
|
||||
resp, response_body = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_state_updated_start_time(self):
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
state_updated_start_time = element['state_updated_timestamp']
|
||||
query_parms = '?state_updated_timestamp=' + \
|
||||
str(state_updated_start_time)
|
||||
resp, response_body = self.monasca_client.list_alarms(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
element_1 = response_body['elements'][0]
|
||||
self.assertEqual(element, element_1)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_by_offset_limit(self):
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
elements = response_body['elements']
|
||||
first_element = elements[0]
|
||||
next_element = elements[1]
|
||||
id = first_element['id']
|
||||
query_parms = '?offset=' + str(id) + '&limit=1'
|
||||
resp, response_body1 = self.monasca_client.list_alarms(query_parms)
|
||||
elements = response_body1['elements']
|
||||
self.assertEqual(1, len(elements))
|
||||
self.assertEqual(elements[0]['id'], next_element['id'])
|
||||
self.assertEqual(elements[0], next_element)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_get_alarm(self):
|
||||
self.create_alarms_for_test_alarms()
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
id = element['id']
|
||||
resp, response_body = self.monasca_client.get_alarm(id)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(set(['id',
|
||||
'links',
|
||||
'alarm_definition',
|
||||
'metrics',
|
||||
'state',
|
||||
'lifecycle_state',
|
||||
'link',
|
||||
'state_updated_timestamp',
|
||||
'updated_timestamp',
|
||||
'created_timestamp']) ==
|
||||
set(response_body))
|
||||
for metric in element['metrics']:
|
||||
target_metric = helpers.create_metric()
|
||||
self.assertEqual(target_metric['name'], metric['name'])
|
||||
self.assertEqual(target_metric['dimensions'], metric['dimensions'])
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_get_alarm_with_invalid_id(self):
|
||||
id = data_utils.rand_name()
|
||||
self.assertRaises(exceptions.NotFound, self.monasca_client.get_alarm,
|
||||
id)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_update_alarm(self):
|
||||
self.create_alarms_for_test_alarms()
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
id = element['id']
|
||||
updated_state = "ALARM"
|
||||
updated_lifecycle_state = "OPEN"
|
||||
updated_link = "http://somesite.com"
|
||||
resp, response_body = self.monasca_client.update_alarm(
|
||||
id=id, state=updated_state,
|
||||
lifecycle_state=updated_lifecycle_state, link=updated_link)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(set(['id',
|
||||
'links',
|
||||
'alarm_definition',
|
||||
'metrics',
|
||||
'state',
|
||||
'lifecycle_state',
|
||||
'link',
|
||||
'state_updated_timestamp',
|
||||
'updated_timestamp',
|
||||
'created_timestamp']) ==
|
||||
set(response_body))
|
||||
|
||||
# Validate fields updated
|
||||
self.assertEqual(updated_state, response_body['state'])
|
||||
self.assertEqual(updated_lifecycle_state, response_body[
|
||||
'lifecycle_state'])
|
||||
self.assertEqual(updated_link, response_body[
|
||||
'link'])
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_patch_alarm(self):
|
||||
self.create_alarms_for_test_alarms()
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
id = element['id']
|
||||
updated_state = "UNDETERMINED"
|
||||
resp, response_body = self.monasca_client.patch_alarm(
|
||||
id=id, state=updated_state)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(set(['id',
|
||||
'links',
|
||||
'alarm_definition',
|
||||
'metrics',
|
||||
'state',
|
||||
'lifecycle_state',
|
||||
'link',
|
||||
'state_updated_timestamp',
|
||||
'updated_timestamp',
|
||||
'created_timestamp']) ==
|
||||
set(response_body))
|
||||
|
||||
# Validate the field patched
|
||||
self.assertEqual(updated_state, response_body['state'])
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_delete_alarm(self):
|
||||
self.create_alarms_for_test_alarms()
|
||||
resp, response_body = self.monasca_client.list_alarms()
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
id = element['id']
|
||||
resp, response_body = self.monasca_client.delete_alarm(id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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)
|
212
monasca_tempest_tests/tests/api/test_alarms_state_history.py
Normal file
212
monasca_tempest_tests/tests/api/test_alarms_state_history.py
Normal file
@ -0,0 +1,212 @@
|
||||
# (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.
|
||||
|
||||
# TODO(RMH): Update documentation. Get alarms returns alarm_definition, not
|
||||
# TODO(RMH): alarm_definition_id in response body
|
||||
import time
|
||||
|
||||
from monasca_tempest_tests.tests.api import base
|
||||
from monasca_tempest_tests.tests.api import helpers
|
||||
from oslo_utils import timeutils
|
||||
from tempest.common.utils import data_utils
|
||||
from tempest import test
|
||||
|
||||
|
||||
class TestAlarmsStateHistory(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestAlarmsStateHistory, cls).resource_setup()
|
||||
|
||||
start_timestamp = int(time.time() * 1000)
|
||||
end_timestamp = int(time.time() * 1000) + 1000
|
||||
|
||||
# create an alarm definition
|
||||
expression = "avg(name-1) > 0"
|
||||
name = data_utils.rand_name('alarm_definition')
|
||||
alarm_definition = helpers.create_alarm_definition(
|
||||
name=name,
|
||||
expression=expression)
|
||||
resp, response_body = cls.monasca_client.create_alarm_definitions(
|
||||
alarm_definition)
|
||||
|
||||
# create another alarm definition
|
||||
name1 = data_utils.rand_name('alarm_definition1')
|
||||
expression1 = "max(cpu.system_perc) > 0"
|
||||
alarm_definition1 = helpers.create_alarm_definition(
|
||||
name=name1,
|
||||
expression=expression1)
|
||||
resp, response_body1 = cls.monasca_client.create_alarm_definitions(
|
||||
alarm_definition1)
|
||||
|
||||
# create another alarm definition
|
||||
name2 = data_utils.rand_name('alarm_definition2')
|
||||
expression1 = "avg(mysql.performance.slow_queries) > 10.0"
|
||||
alarm_definition2 = helpers.create_alarm_definition(
|
||||
name=name2,
|
||||
expression=expression1)
|
||||
resp, response_body2 = cls.monasca_client.create_alarm_definitions(
|
||||
alarm_definition2)
|
||||
|
||||
# create some metrics
|
||||
for i in xrange(180):
|
||||
metric = helpers.create_metric()
|
||||
resp, body = cls.monasca_client.create_metrics(metric)
|
||||
cls._start_timestamp = start_timestamp + i
|
||||
cls._end_timestamp = end_timestamp + i
|
||||
time.sleep(1)
|
||||
resp, response_body = cls.monasca_client.\
|
||||
list_alarms_state_history()
|
||||
elements = response_body['elements']
|
||||
if len(elements) > 4:
|
||||
break
|
||||
|
||||
if len(elements) < 3:
|
||||
cls.assertEqual(1, False)
|
||||
|
||||
@test.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']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id', 'alarm_id', 'metrics', 'old_state',
|
||||
'new_state', 'reason', 'reason_data', 'timestamp',
|
||||
'sub_alarms']) == set(element))
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_state_history_with_dimensions(self):
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history()
|
||||
element = response_body['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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_state_history_with_start_time(self):
|
||||
current_time = int(time.time())
|
||||
current_time = timeutils.iso8601_from_timestamp(current_time)
|
||||
query_parms = '?start_time=' + str(current_time)
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history(
|
||||
query_parms)
|
||||
elements = response_body['elements']
|
||||
self.assertEqual(0, len(elements))
|
||||
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history()
|
||||
elements = response_body['elements']
|
||||
timestamp = elements[1]['timestamp']
|
||||
query_parms = '?start_time=' + str(timestamp)
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history(
|
||||
query_parms)
|
||||
elements = response_body['elements']
|
||||
self.assertEqual(2, len(elements))
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_state_history_with_end_time(self):
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history()
|
||||
elements = response_body['elements']
|
||||
timestamp = elements[2]['timestamp']
|
||||
query_parms = '?end_time=' + str(timestamp)
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history(
|
||||
query_parms)
|
||||
elements = response_body['elements']
|
||||
self.assertEqual(1, len(elements))
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_alarms_state_history_with_offset_limit(self):
|
||||
resp, response_body = self.monasca_client.list_alarms_state_history()
|
||||
elements = response_body['elements']
|
||||
first_element = elements[0]
|
||||
last_element = elements[2]
|
||||
first_element_id = first_element['id']
|
||||
last_element_id = last_element['id']
|
||||
|
||||
for limit in xrange(1, 4):
|
||||
query_parms = '?limit=' + str(limit) + '&offset=' + str(
|
||||
last_element_id)
|
||||
resp, response_body = self.monasca_client.\
|
||||
list_alarms_state_history(query_parms)
|
||||
elements = response_body['elements']
|
||||
element_new = elements[0]
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(element_new, first_element)
|
||||
self.assertEqual(limit, len(elements))
|
||||
id_new = element_new['id']
|
||||
self.assertEqual(id_new, first_element_id)
|
||||
|
||||
@test.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']
|
||||
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.assertTrue(isinstance(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))
|
||||
|
||||
@test.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']
|
||||
element = elements[0]
|
||||
|
||||
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))
|
||||
|
||||
id = element['id']
|
||||
query_parms = '?limit=1&offset=' + str(id)
|
||||
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(element, elements_new[0])
|
221
monasca_tempest_tests/tests/api/test_measurements.py
Normal file
221
monasca_tempest_tests/tests/api/test_measurements.py
Normal file
@ -0,0 +1,221 @@
|
||||
# (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 time
|
||||
|
||||
from oslo_utils import timeutils
|
||||
|
||||
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.common.utils import data_utils
|
||||
from tempest import test
|
||||
from tempest_lib import exceptions
|
||||
|
||||
NUM_MEASUREMENTS = 100
|
||||
WAIT_TIME = 30
|
||||
|
||||
|
||||
class TestMeasurements(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestMeasurements, cls).resource_setup()
|
||||
|
||||
start_timestamp = int(time.time() * 1000)
|
||||
end_timestamp = int(time.time() * 1000) + NUM_MEASUREMENTS * 1000
|
||||
metrics = []
|
||||
|
||||
for i in xrange(NUM_MEASUREMENTS):
|
||||
metric = helpers.create_metric(
|
||||
name="name-1",
|
||||
timestamp=start_timestamp + i)
|
||||
metrics.append(metric)
|
||||
|
||||
resp, response_body = cls.monasca_client.create_metrics(metrics)
|
||||
cls._start_timestamp = start_timestamp
|
||||
cls._end_timestamp = end_timestamp
|
||||
cls._metrics = metrics
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&start_time=' + str(
|
||||
start_time)
|
||||
resp, response_body = self.monasca_client.list_measurements(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
self.assertTrue(set(['links', 'elements']) == set(response_body))
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id', 'name', 'dimensions', 'columns',
|
||||
'measurements']) == set(element))
|
||||
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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_measurements_with_no_start_time(self):
|
||||
query_parms = '?name=name-1'
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_measurements, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_measurements_with_no_name(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?start_time=' + str(start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_measurements, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements_with_dimensions(self):
|
||||
key1 = data_utils.rand_name('key1')
|
||||
value1 = data_utils.rand_name('value1')
|
||||
start_timestamp = int(time.time() * 1000)
|
||||
name = data_utils.rand_name()
|
||||
metric = [
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp,
|
||||
dimensions={key1: value1}, value=123)
|
||||
]
|
||||
resp, response_body = self.monasca_client.create_metrics(metric)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=' + name + '&start_time=' + str(
|
||||
start_time) + '&dimensions=' + key1 + ':' + value1
|
||||
resp, response_body = self.monasca_client.list_measurements(
|
||||
query_parms)
|
||||
value_new = response_body['elements'][0]['measurements'][0][1]
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(123, value_new)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements_with_endtime(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
end_time = timeutils.iso8601_from_timestamp(
|
||||
self._end_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&true&start_time=' + str(
|
||||
start_time) + '&end_time' + str(end_time)
|
||||
resp, body = self.monasca_client.list_measurements(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
len_measurements = len(body['elements'][0]['measurements'])
|
||||
self.assertEqual(len_measurements, NUM_MEASUREMENTS)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements_with_offset_limit(self):
|
||||
start_timestamp = int(time.time() * 1000)
|
||||
name = data_utils.rand_name()
|
||||
metric = [
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 0,
|
||||
dimensions={'key1': 'value-1',
|
||||
'key2': 'value-1'}),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 1,
|
||||
dimensions={'key1': 'value-2',
|
||||
'key2': 'value-2'}),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 2,
|
||||
dimensions={'key1': 'value-3',
|
||||
'key2': 'value-3'}),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 3,
|
||||
dimensions={'key1': 'value-4',
|
||||
'key2': 'value-4'})
|
||||
]
|
||||
|
||||
resp, response_body = self.monasca_client.create_metrics(metric)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
query_parms = '?name=' + name
|
||||
resp, response_body = self.monasca_client.list_metrics(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
start_timestamp / 1000)
|
||||
query_parms = '?name=' + name + '&merge_metrics=true&start_time=' + \
|
||||
str(start_time)
|
||||
resp, body = self.monasca_client.list_measurements(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = body['elements'][0]['measurements']
|
||||
first_element = elements[0]
|
||||
last_element = elements[3]
|
||||
|
||||
query_parms = '?name=' + name + '&merge_metrics=true&start_time=' + \
|
||||
str(start_time) + '&limit=4'
|
||||
resp, response_body = self.monasca_client.list_measurements(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
elements = response_body['elements'][0]['measurements']
|
||||
self.assertEqual(4, len(elements))
|
||||
|
||||
self.assertEqual(first_element, elements[0])
|
||||
|
||||
for limit in xrange(1, 5):
|
||||
next_element = elements[limit - 1]
|
||||
while True:
|
||||
query_parms = '?name=' + name + \
|
||||
'&merge_metrics=true&start_time=' + \
|
||||
str(start_time) + '&offset=' + \
|
||||
str(next_element[0]) + '&limit=' + \
|
||||
str(limit)
|
||||
resp, response_body = self.monasca_client.list_measurements(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
new_elements = response_body['elements'][0]['measurements']
|
||||
|
||||
if len(new_elements) > limit - 1:
|
||||
self.assertEqual(limit, len(new_elements))
|
||||
next_element = new_elements[limit - 1]
|
||||
elif len(new_elements) > 0 and len(new_elements) <= limit - 1:
|
||||
self.assertEqual(last_element, new_elements[0])
|
||||
break
|
||||
else:
|
||||
self.assertEqual(last_element, next_element)
|
||||
break
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements_with_merge_metrics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&start_time=' + str(
|
||||
start_time)
|
||||
resp, response_body = self.monasca_client.list_measurements(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_measurements_with_name_exceeds_max_length(self):
|
||||
long_name = "x" * (constants.MAX_LIST_MEASUREMENTS_NAME_LENGTH + 1)
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp
|
||||
/ 1000)
|
||||
query_parms = '?name=' + str(long_name) \
|
||||
+ '&merge_metrics=true&start_time=' + str(start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_measurements, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_measurements_with_no_merge_metrics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=false&start_time=' + str(
|
||||
start_time)
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.monasca_client.list_measurements, query_parms)
|
236
monasca_tempest_tests/tests/api/test_metrics.py
Normal file
236
monasca_tempest_tests/tests/api/test_metrics.py
Normal file
@ -0,0 +1,236 @@
|
||||
# (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.
|
||||
|
||||
# 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 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.common.utils import data_utils
|
||||
from tempest import test
|
||||
from tempest_lib import exceptions
|
||||
|
||||
WAIT_TIME = 30
|
||||
|
||||
|
||||
class TestMetrics(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestMetrics, cls).resource_setup()
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_create_metric(self):
|
||||
metric = helpers.create_metric()
|
||||
resp, body = self.monasca_client.create_metrics(metric)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_create_metrics(self):
|
||||
metrics = [
|
||||
helpers.create_metric(),
|
||||
helpers.create_metric()
|
||||
]
|
||||
resp, body = self.monasca_client.create_metrics(metrics)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.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)
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_create_metric_with_no_dimensions(self):
|
||||
metric = helpers.create_metric(dimensions=None)
|
||||
resp, body = self.monasca_client.create_metrics(metric)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_metric_with_no_timestamp(self):
|
||||
metric = helpers.create_metric(timestamp=None)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_metrics,
|
||||
metric)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_metric_no_value(self):
|
||||
timestamp = time.time() * 1000
|
||||
metric = helpers.create_metric(timestamp=timestamp,
|
||||
value=None)
|
||||
return
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_metrics,
|
||||
metric)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.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)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_metric_with_invalid_chars_in_name(self):
|
||||
for invalid_char in constants.INVALID_CHARS:
|
||||
metric = helpers.create_metric(invalid_char)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_metrics,
|
||||
metric)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_metric_with_invalid_chars_in_dimensions(self):
|
||||
for invalid_char in constants.INVALID_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_CHARS:
|
||||
metric = helpers.create_metric('name-1', {invalid_char: 'value-1'})
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_metrics,
|
||||
metric)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.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)
|
||||
|
||||
@test.attr(type='gate')
|
||||
@test.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)
|
||||
|
||||
@test.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.assertTrue(set(['id', 'name', 'dimensions']) == set(element))
|
||||
self.assertTrue(type(element['id']) is unicode)
|
||||
self.assertTrue(type(element['name']) is unicode)
|
||||
self.assertTrue(type(element['dimensions']) is dict)
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_metrics_with_name(self):
|
||||
name_org = data_utils.rand_name('name')
|
||||
key = data_utils.rand_name('key')
|
||||
metric = helpers.create_metric(name=name_org,
|
||||
dimensions={key: 'value-1'})
|
||||
resp, body = self.monasca_client.create_metrics(metric)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
query_parms = '?dimensions=' + str(key) + ':value-1'
|
||||
resp, response_body = self.monasca_client.list_metrics(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
dimensions = elements[0]
|
||||
name = dimensions['name']
|
||||
self.assertEqual(name_org, str(name))
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_metrics_with_dimensions(self):
|
||||
name = data_utils.rand_name('name')
|
||||
key = data_utils.rand_name('key')
|
||||
value_org = data_utils.rand_name('value')
|
||||
metric = helpers.create_metric(name=name,
|
||||
dimensions={key: value_org})
|
||||
resp, body = self.monasca_client.create_metrics(metric)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
query_parms = '?name=' + name
|
||||
resp, response_body = self.monasca_client.list_metrics(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements']
|
||||
dimensions = elements[0]
|
||||
dimension = dimensions['dimensions']
|
||||
value = dimension[unicode(key)]
|
||||
self.assertEqual(value_org, str(value))
|
||||
|
||||
@test.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'})
|
||||
]
|
||||
resp, body = self.monasca_client.create_metrics(metrics)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
query_parms = '?name=' + name
|
||||
resp, response_body = self.monasca_client.list_metrics(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
elements = response_body['elements']
|
||||
first_element = elements[0]
|
||||
last_element = elements[3]
|
||||
|
||||
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 limit in xrange(1, 5):
|
||||
next_element = elements[limit - 1]
|
||||
while True:
|
||||
query_parms = '?name=' + name + '&offset=' +\
|
||||
str(next_element['id']) + '&limit=' + str(limit)
|
||||
resp, response_body = self.monasca_client.list_metrics(
|
||||
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]
|
||||
elif len(new_elements) > 0 and len(new_elements) <= limit - 1:
|
||||
self.assertEqual(last_element, new_elements[0])
|
||||
break
|
||||
else:
|
||||
self.assertEqual(last_element, next_element)
|
||||
break
|
47
monasca_tempest_tests/tests/api/test_metrics_names.py
Normal file
47
monasca_tempest_tests/tests/api/test_metrics_names.py
Normal file
@ -0,0 +1,47 @@
|
||||
# (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 monasca_tempest_tests.tests.api import base
|
||||
from tempest import test
|
||||
|
||||
|
||||
class TestMetricsNames(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestMetricsNames, cls).resource_setup()
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_metrics_names(self):
|
||||
resp, response_body = self.monasca_client.list_metrics_names()
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertTrue(set(['links', 'elements']) == set(response_body))
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id', 'name']) == set(element))
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_metrics_names_with_dimensions(self):
|
||||
query_parms = '?dimensions=key1:value1'
|
||||
resp, response_body = self.monasca_client.list_metrics_names(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_list_metrics_names_with_limit_offset(self):
|
||||
# Can not test list_metrics_names_with_limit_offset for now because
|
||||
# list_metrics_names returns a list of metric names with no
|
||||
# duplicates. But the limit and offset are using the original list
|
||||
# with duplicates as reference.
|
||||
return
|
297
monasca_tempest_tests/tests/api/test_notification_methods.py
Normal file
297
monasca_tempest_tests/tests/api/test_notification_methods.py
Normal file
@ -0,0 +1,297 @@
|
||||
# (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.
|
||||
|
||||
# TODO(RMH): Validate whether a 200 or 201 should be returned and resolve.
|
||||
# TODO(RMH): Documentation says 200, but a 201 is being returned.
|
||||
|
||||
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.common.utils import data_utils
|
||||
from tempest import test
|
||||
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()
|
||||
|
||||
@test.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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_notification_method_with_no_name(self):
|
||||
notification = helpers.create_notification(name=None)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_notification_method_with_no_type(self):
|
||||
notification = helpers.create_notification(type=None)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_notification_method_with_no_address(self):
|
||||
notification = helpers.create_notification(address=None)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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.UnprocessableEntity,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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.UnprocessableEntity,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_create_notification_method_with_invalid_type(self):
|
||||
notification = helpers.create_notification(type='random')
|
||||
self.assertRaises(exceptions.BadRequest,
|
||||
self.monasca_client.create_notifications,
|
||||
notification)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_notification_methods(self):
|
||||
resp, body = self.monasca_client.list_notification_methods()
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_notification_methods_with_offset_limit(self):
|
||||
query_parms = '?offset=1&limit=2'
|
||||
resp, body = self.monasca_client.list_notification_methods(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_notification_methods_response_body(self):
|
||||
# TODO(RMH): Validate response body
|
||||
resp, response_body = self.monasca_client.list_notification_methods()
|
||||
self.assertTrue(set(['links', 'elements']) == set(response_body))
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id', 'links', 'name', 'type', 'address']) ==
|
||||
set(element))
|
||||
# check if 'id' is an int. NOPE its unicode
|
||||
self.assertTrue(type(element['id']) is unicode)
|
||||
# check if 'links' is link
|
||||
self.assertTrue(type(element['links']) is list)
|
||||
# check if 'name' is a string. NOPE its unicode
|
||||
self.assertTrue(type(element['name']) is unicode)
|
||||
# check if 'type' is an unicode
|
||||
self.assertTrue(type(element['type']) is unicode)
|
||||
# check if 'address' is an unicode
|
||||
self.assertTrue(type(element['address']) is unicode)
|
||||
|
||||
@test.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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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)
|
||||
|
||||
@test.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'])
|
||||
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)
|
||||
|
||||
@test.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'])
|
||||
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)
|
||||
|
||||
@test.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)
|
||||
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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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.UnprocessableEntity,
|
||||
self.monasca_client.update_notification_method, id,
|
||||
name=new_name_long, type=response_body['type'],
|
||||
address=response_body['address'])
|
||||
resp, response_body = \
|
||||
self.monasca_client.delete_notification_method(id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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,
|
||||
self.monasca_client.update_notification_method, id,
|
||||
name=response_body['name'], type='random',
|
||||
address=response_body['address'])
|
||||
resp, response_body = \
|
||||
self.monasca_client.delete_notification_method(id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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,
|
||||
self.monasca_client.update_notification_method, id,
|
||||
name=response_body['name'], type=new_address_long,
|
||||
address=response_body['address'])
|
||||
resp, response_body = \
|
||||
self.monasca_client.delete_notification_method(id)
|
||||
self.assertEqual(204, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_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)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.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)
|
301
monasca_tempest_tests/tests/api/test_statistics.py
Normal file
301
monasca_tempest_tests/tests/api/test_statistics.py
Normal file
@ -0,0 +1,301 @@
|
||||
# (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 time
|
||||
|
||||
from oslo_utils import timeutils
|
||||
|
||||
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.common.utils import data_utils
|
||||
from tempest import test
|
||||
from tempest_lib import exceptions
|
||||
|
||||
NUM_MEASUREMENTS = 100
|
||||
WAIT_TIME = 30
|
||||
|
||||
|
||||
class TestStatistics(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestStatistics, cls).resource_setup()
|
||||
|
||||
start_timestamp = int(time.time() * 1000)
|
||||
end_timestamp = int(time.time() * 1000) + NUM_MEASUREMENTS * 1000
|
||||
metrics = []
|
||||
|
||||
for i in xrange(NUM_MEASUREMENTS):
|
||||
metric = helpers.create_metric(
|
||||
name="name-1",
|
||||
timestamp=start_timestamp + i)
|
||||
metrics.append(metric)
|
||||
|
||||
resp, response_body = cls.monasca_client.create_metrics(metric)
|
||||
cls._start_timestamp = start_timestamp
|
||||
cls._end_timestamp = end_timestamp
|
||||
cls._metrics = metrics
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
super(TestStatistics, cls).resource_cleanup()
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp /
|
||||
1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg' \
|
||||
'&start_time=' + str(start_time)
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
self.assertTrue(set(['links', 'elements']) == set(response_body))
|
||||
elements = response_body['elements']
|
||||
element = elements[0]
|
||||
self.assertTrue(set(['id', 'name', 'dimensions', 'columns',
|
||||
'statistics']) == set(element))
|
||||
# check if 'id' is unicode type
|
||||
self.assertTrue(type(element['id']) is unicode)
|
||||
# check if 'name' is a string. NOPE its unicode
|
||||
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['statistics']) is list)
|
||||
statistic = element['statistics']
|
||||
column = element['columns']
|
||||
self.assertTrue(type(statistic) is list)
|
||||
self.assertTrue(type(column) is list)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_no_name(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp /
|
||||
1000)
|
||||
query_parms = '?merge_metrics=true&statistics=avg&start_time=' + \
|
||||
str(start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_no_statistics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp /
|
||||
1000)
|
||||
query_parms = '?name=name-1&start_time=' + str(start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_no_start_time(self):
|
||||
query_parms = '?name=name-1&statistics=avg'
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_invalid_statistics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&statistics=abc&start_time=' + str(
|
||||
start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_with_dimensions(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp
|
||||
/ 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg&' \
|
||||
'start_time=' + str(start_time) + \
|
||||
'&dimensions=key1:value1'
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_with_end_time(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
end_time = timeutils.iso8601_from_timestamp(
|
||||
self._end_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg&' \
|
||||
'start_time=' + str(start_time) + '&end_time=' + \
|
||||
str(end_time)
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_with_period(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg&' \
|
||||
'start_time=' + str(start_time) + '&period=300'
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.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 + 0,
|
||||
dimensions={'key1': 'value-1',
|
||||
'key2': 'value-1'},
|
||||
value=1),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 500,
|
||||
dimensions={'key1': 'value-2',
|
||||
'key2': 'value-2'},
|
||||
value=2),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 1000,
|
||||
dimensions={'key1': 'value-3',
|
||||
'key2': 'value-3'},
|
||||
value=3),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 1500,
|
||||
dimensions={'key1': 'value-4',
|
||||
'key2': 'value-4'},
|
||||
value=4),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 2000,
|
||||
dimensions={'key1': 'value-2',
|
||||
'key2': 'value-2'},
|
||||
value=5),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 2500,
|
||||
dimensions={'key1': 'value-3',
|
||||
'key2': 'value-3'},
|
||||
value=6),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 3000,
|
||||
dimensions={'key1': 'value-4',
|
||||
'key2': 'value-4'},
|
||||
value=7),
|
||||
helpers.create_metric(name=name, timestamp=start_timestamp + 3500,
|
||||
dimensions={'key1': 'value-4',
|
||||
'key2': 'value-4'},
|
||||
value=8)
|
||||
]
|
||||
|
||||
resp, response_body = self.monasca_client.create_metrics(metric)
|
||||
time.sleep(WAIT_TIME)
|
||||
|
||||
query_parms = '?name=' + name
|
||||
resp, response_body = self.monasca_client.list_metrics(query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
start_timestamp / 1000)
|
||||
end_timestamp = start_timestamp + 4000
|
||||
end_time = timeutils.iso8601_from_timestamp(end_timestamp / 1000)
|
||||
query_parms = '?name=' + name + '&merge_metrics=true&statistics=avg,' \
|
||||
'max,min,sum,count&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]
|
||||
last_element = elements[3]
|
||||
|
||||
query_parms = '?name=' + name + '&merge_metrics=true&statistics=avg,' \
|
||||
'max,min,sum,count&start_time=' + str(start_time) + \
|
||||
'&end_time=' + str(end_time) + '&period=1' + '&limit=4'
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
elements = response_body['elements'][0]['statistics']
|
||||
self.assertEqual(4, len(elements))
|
||||
self.assertEqual(first_element, elements[0])
|
||||
|
||||
for limit in xrange(1, 5):
|
||||
next_element = elements[limit - 1]
|
||||
offset_timestamp = start_timestamp
|
||||
while True:
|
||||
offset_timestamp += 1000 * limit
|
||||
offset = timeutils.iso8601_from_timestamp(offset_timestamp /
|
||||
1000)
|
||||
query_parms = '?name=' + name + '&merge_metrics=true' + \
|
||||
'&statistics=avg,max,min,sum,' \
|
||||
'count&start_time=' + str(start_time) + \
|
||||
'&end_time=' + str(end_time) + '&period=1' + \
|
||||
'&limit=' + str(limit) + '&offset=' + str(offset)
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
new_elements = response_body['elements'][0]['statistics']
|
||||
|
||||
if len(new_elements) > limit - 1:
|
||||
self.assertEqual(limit, len(new_elements))
|
||||
next_element = new_elements[limit - 1]
|
||||
elif len(new_elements) > 0 and len(new_elements) <= limit - 1:
|
||||
self.assertEqual(last_element, new_elements[0])
|
||||
break
|
||||
else:
|
||||
self.assertEqual(last_element, next_element)
|
||||
break
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_with_merge_metrics(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(
|
||||
self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg&' \
|
||||
'merge_metrics=true&start_time=' + str(start_time)
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_no_merge_metrics(self):
|
||||
start_time = timeutils.\
|
||||
iso8601_from_timestamp(self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=false&' \
|
||||
'statistics=avg,min,max&start_time=' + str(start_time)
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
@test.attr(type=['negative'])
|
||||
def test_list_statistics_with_name_exceeds_max_length(self):
|
||||
long_name = "x" * (constants.MAX_LIST_STATISTICS_NAME_LENGTH + 1)
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp
|
||||
/ 1000)
|
||||
query_parms = '?merge_metrics=true&name=' + str(long_name) + \
|
||||
'&start_time=' + str(start_time)
|
||||
self.assertRaises(exceptions.UnprocessableEntity,
|
||||
self.monasca_client.list_statistics, query_parms)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_with_more_than_one_statistics(self):
|
||||
start_time = timeutils.\
|
||||
iso8601_from_timestamp(self._start_timestamp / 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&' \
|
||||
'statistics=avg,min,max&start_time=' + str(start_time)
|
||||
resp, response_body = self.monasca_client.list_statistics(
|
||||
query_parms)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
@test.attr(type="gate")
|
||||
def test_list_statistics_response_body_statistic_result_type(self):
|
||||
start_time = timeutils.iso8601_from_timestamp(self._start_timestamp
|
||||
/ 1000)
|
||||
query_parms = '?name=name-1&merge_metrics=true&statistics=avg&' \
|
||||
'start_time=' + str(start_time)
|
||||
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)
|
51
monasca_tempest_tests/tests/api/test_versions.py
Normal file
51
monasca_tempest_tests/tests/api/test_versions.py
Normal file
@ -0,0 +1,51 @@
|
||||
# (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 datetime
|
||||
|
||||
from oslo_serialization import jsonutils as json
|
||||
|
||||
from monasca_tempest_tests.tests.api import base
|
||||
from tempest import test
|
||||
|
||||
|
||||
class TestVersions(base.BaseMonascaTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestVersions, cls).resource_setup()
|
||||
|
||||
@test.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.assertTrue(isinstance(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.assertTrue(isinstance(date_object, datetime.datetime))
|
||||
links = response_body['links']
|
||||
self.assertTrue(isinstance(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'))
|
||||
return
|
@ -20,9 +20,10 @@ classifier =
|
||||
[files]
|
||||
packages =
|
||||
monasca_api
|
||||
monasca_tempest_tests
|
||||
|
||||
data_files =
|
||||
/etc/monasca =
|
||||
etc/monasca =
|
||||
etc/api-config.conf
|
||||
etc/api-config.ini
|
||||
|
||||
@ -30,5 +31,8 @@ data_files =
|
||||
console_scripts =
|
||||
monasca-api = monasca_api.api.server:launch
|
||||
|
||||
tempest.test_plugins =
|
||||
monasca_tests = monasca_tempest_tests.plugin:MonascaTempestPlugin
|
||||
|
||||
[pbr]
|
||||
warnerrors = True
|
2
tox.ini
2
tox.ini
@ -9,7 +9,7 @@ usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = nosetests
|
||||
commands = python setup.py testr --testr-args='{posargs}'
|
||||
|
||||
[testenv:cover]
|
||||
setenv = NOSE_WITH_COVERAGE=1
|
||||
|
Loading…
Reference in New Issue
Block a user