Add basic Ceilometer alarm test
This sends a manual ceilometer sample to trigger the alarm, then confirms that the autoscale policy/group reacts correctly. Note: this doesn't used ScenarioBaseTest as it skips the test unnecessarily on unused images and networks. Change-Id: I5c842779d90497ba88df66bbfd8f447679645192 Depends-On: Ib3795bcca9d5ec3d68c6443a9854dbc56118ca40
This commit is contained in:
parent
4032e40cce
commit
5fa6559b0b
@ -12,6 +12,7 @@
|
||||
|
||||
import os
|
||||
|
||||
import ceilometerclient.client
|
||||
import cinderclient.client
|
||||
import heatclient.client
|
||||
import keystoneclient.exceptions
|
||||
@ -30,6 +31,7 @@ class ClientManager(object):
|
||||
CINDERCLIENT_VERSION = '1'
|
||||
HEATCLIENT_VERSION = '1'
|
||||
NOVACLIENT_VERSION = '2'
|
||||
CEILOMETER_VERSION = '2'
|
||||
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
@ -39,6 +41,7 @@ class ClientManager(object):
|
||||
self.network_client = self._get_network_client()
|
||||
self.volume_client = self._get_volume_client()
|
||||
self.object_client = self._get_object_client()
|
||||
self.metering_client = self._get_metering_client()
|
||||
|
||||
def _get_orchestration_client(self):
|
||||
region = self.conf.region
|
||||
@ -136,3 +139,27 @@ class ClientManager(object):
|
||||
'insecure': dscv,
|
||||
}
|
||||
return swiftclient.client.Connection(**args)
|
||||
|
||||
def _get_metering_client(self):
|
||||
dscv = self.conf.disable_ssl_certificate_validation
|
||||
|
||||
keystone = self._get_identity_client()
|
||||
endpoint = keystone.service_catalog.url_for(
|
||||
attr='region',
|
||||
filter_value=self.conf.region,
|
||||
service_type='metering',
|
||||
endpoint_type='publicURL')
|
||||
|
||||
args = {
|
||||
'username': self.conf.username,
|
||||
'password': self.conf.password,
|
||||
'tenant_name': self.conf.tenant_name,
|
||||
'auth_url': self.conf.auth_url,
|
||||
'insecure': dscv,
|
||||
'region_name': self.conf.region,
|
||||
'endpoint_type': 'publicURL',
|
||||
'service_type': 'metering',
|
||||
}
|
||||
|
||||
return ceilometerclient.client.Client(self.CEILOMETER_VERSION,
|
||||
endpoint, **args)
|
||||
|
@ -87,6 +87,7 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
|
||||
self.network_client = self.manager.network_client
|
||||
self.volume_client = self.manager.volume_client
|
||||
self.object_client = self.manager.object_client
|
||||
self.metering_client = self.manager.metering_client
|
||||
self.useFixture(fixtures.FakeLogger(format=_LOG_FORMAT))
|
||||
self.updated_time = {}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
localrc_path=$BASE/new/devstack/localrc
|
||||
localconf=$BASE/new/devstack/local.conf
|
||||
|
||||
echo "CEILOMETER_PIPELINE_INTERVAL=60" >> $localrc_path
|
||||
echo "HEAT_ENABLE_ADOPT_ABANDON=True" >> $localrc_path
|
||||
echo -e '[[post-config|$HEAT_CONF]]\n[DEFAULT]\n' >> $localconf
|
||||
echo -e 'notification_driver=messagingv2\n' >> $localconf
|
||||
|
@ -4,6 +4,7 @@ oslo.messaging>=1.8.0,<1.9.0 # Apache-2.0
|
||||
oslo.config>=1.9.3,<1.10.0 # Apache-2.0
|
||||
oslo.utils>=1.4.0,<1.5.0 # Apache-2.0
|
||||
paramiko>=1.13.0
|
||||
python-ceilometerclient>=1.0.13
|
||||
python-cinderclient>=1.1.0
|
||||
python-keystoneclient>=1.1.0
|
||||
python-heatclient>=0.3.0
|
||||
|
@ -0,0 +1,33 @@
|
||||
heat_template_version: 2013-05-23
|
||||
resources:
|
||||
asg:
|
||||
type: OS::Heat::AutoScalingGroup
|
||||
properties:
|
||||
max_size: 5
|
||||
min_size: 1
|
||||
resource:
|
||||
type: OS::Heat::RandomString
|
||||
scaleup_policy:
|
||||
type: OS::Heat::ScalingPolicy
|
||||
properties:
|
||||
adjustment_type: change_in_capacity
|
||||
auto_scaling_group_id: {get_resource: asg}
|
||||
cooldown: 0
|
||||
scaling_adjustment: 1
|
||||
alarm:
|
||||
type: OS::Ceilometer::Alarm
|
||||
properties:
|
||||
description: Scale-up if the average CPU > 50% for 1 minute
|
||||
meter_name: test_meter
|
||||
statistic: count
|
||||
comparison_operator: ge
|
||||
threshold: 1
|
||||
period: 60
|
||||
evaluation_periods: 1
|
||||
alarm_actions:
|
||||
- {get_attr: [scaleup_policy, alarm_url]}
|
||||
matching_metadata:
|
||||
metadata.metering.stack_id: {get_param: "OS::stack_id"}
|
||||
outputs:
|
||||
asg_size:
|
||||
value: {get_attr: [asg, current_size]}
|
57
heat_integrationtests/scenario/test_ceilometer_alarm.py
Normal file
57
heat_integrationtests/scenario/test_ceilometer_alarm.py
Normal file
@ -0,0 +1,57 @@
|
||||
# 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_log import log as logging
|
||||
|
||||
from heat_integrationtests.common import test
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CeilometerAlarmTest(test.HeatIntegrationTest):
|
||||
"""Class is responsible for testing of ceilometer usage."""
|
||||
def setUp(self):
|
||||
super(CeilometerAlarmTest, self).setUp()
|
||||
self.client = self.orchestration_client
|
||||
self.template = self._load_template(__file__,
|
||||
'test_ceilometer_alarm.yaml',
|
||||
'templates')
|
||||
|
||||
def check_instance_count(self, stack_identifier, expected):
|
||||
stack = self.client.stacks.get(stack_identifier)
|
||||
actual = self._stack_output(stack, 'asg_size')
|
||||
if actual != expected:
|
||||
LOG.warn('check_instance_count exp:%d, act:%s' % (expected,
|
||||
actual))
|
||||
return actual == expected
|
||||
|
||||
def test_alarm(self):
|
||||
"""Confirm we can create an alarm and trigger it."""
|
||||
|
||||
# 1. create the stack
|
||||
stack_identifier = self.stack_create(template=self.template)
|
||||
|
||||
# 2. send ceilometer a metric (should cause the alarm to fire)
|
||||
sample = {}
|
||||
sample['counter_type'] = 'gauge'
|
||||
sample['counter_name'] = 'test_meter'
|
||||
sample['counter_volume'] = 1
|
||||
sample['counter_unit'] = 'count'
|
||||
sample['resource_metadata'] = {'metering.stack_id':
|
||||
stack_identifier.split('/')[-1]}
|
||||
sample['resource_id'] = 'shouldnt_matter'
|
||||
self.metering_client.samples.create(**sample)
|
||||
|
||||
# 3. confirm we get a scaleup.
|
||||
# Note: there is little point waiting more than 60s+time to scale up.
|
||||
self.assertTrue(test.call_until_true(
|
||||
120, 2, self.check_instance_count, stack_identifier, 2))
|
Loading…
Reference in New Issue
Block a user