heat tempests
Change-Id: I63830b715ea8fc9255db4d604ebf75d22eb00b7e
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
export DEVSTACK_GATE_NEUTRON=1
|
export DEVSTACK_GATE_NEUTRON=1
|
||||||
|
export DEVSTACK_GATE_HEAT=1
|
||||||
export DEVSTACK_GATE_INSTALL_TESTONLY=1
|
export DEVSTACK_GATE_INSTALL_TESTONLY=1
|
||||||
export DEVSTACK_GATE_TEMPEST=1
|
export DEVSTACK_GATE_TEMPEST=1
|
||||||
export DEVSTACK_GATE_TEMPEST_NOTESTS=1
|
export DEVSTACK_GATE_TEMPEST_NOTESTS=1
|
||||||
@@ -23,18 +24,19 @@ export KEEP_LOCALRC=1
|
|||||||
if [ -z ${DEVSTACK_LOCAL_CONFIG+x} ]; then
|
if [ -z ${DEVSTACK_LOCAL_CONFIG+x} ]; then
|
||||||
DEVSTACK_LOCAL_CONFIG="enable_plugin vitrage git://git.openstack.org/openstack/vitrage"
|
DEVSTACK_LOCAL_CONFIG="enable_plugin vitrage git://git.openstack.org/openstack/vitrage"
|
||||||
fi
|
fi
|
||||||
#DEVSTACK_LOCAL_CONFIG+=$'\nenable_plugin ceilometer git://git.openstack.org/openstack/ceilometer'
|
DEVSTACK_LOCAL_CONFIG+=$'\nenable_plugin ceilometer git://git.openstack.org/openstack/ceilometer'
|
||||||
#DEVSTACK_LOCAL_CONFIG+=$'\nenable_plugin aodh git://git.openstack.org/openstack/aodh'
|
DEVSTACK_LOCAL_CONFIG+=$'\nenable_plugin aodh git://git.openstack.org/openstack/aodh'
|
||||||
#DEVSTACK_LOCAL_CONFIG+=$'\ndisable_service ceilometer-alarm-evaluator,ceilometer-alarm-notifier'
|
DEVSTACK_LOCAL_CONFIG+=$'\ndisable_service ceilometer-alarm-evaluator,ceilometer-alarm-notifier'
|
||||||
#DEVSTACK_LOCAL_CONFIG+=$'\ndisable_service n-net'
|
DEVSTACK_LOCAL_CONFIG+=$'\ndisable_service n-net'
|
||||||
|
|
||||||
export DEVSTACK_LOCAL_CONFIG
|
export DEVSTACK_LOCAL_CONFIG
|
||||||
|
|
||||||
if [ -z ${ENABLED_SERVICES+x} ]; then
|
if [ -z ${ENABLED_SERVICES+x} ]; then
|
||||||
ENABLED_SERVICES=tempest
|
ENABLED_SERVICES=tempest
|
||||||
fi
|
fi
|
||||||
ENABLED_SERVICES+=,vitrage-api,vitrage-graph
|
|
||||||
ENABLED_SERVICES+=,q-svc,q-dhcp,q-meta,q-agt,q-l3
|
ENABLED_SERVICES+=,q-svc,q-dhcp,q-meta,q-agt,q-l3
|
||||||
|
ENABLED_SERVICES+=,h-eng h-api h-api-cfn h-api-cw
|
||||||
|
ENABLED_SERVICES+=,vitrage-api,vitrage-graph
|
||||||
ENABLED_SERVICES+=,key,aodi-api,aodh-notifier,aodh-evaluator
|
ENABLED_SERVICES+=,key,aodi-api,aodh-notifier,aodh-evaluator
|
||||||
ENABLED_SERVICES+=,ceilometer-alarm-evaluator,ceilometer-alarm-notifier
|
ENABLED_SERVICES+=,ceilometer-alarm-evaluator,ceilometer-alarm-notifier
|
||||||
ENABLED_SERVICES+=,ceilometer-api
|
ENABLED_SERVICES+=,ceilometer-api
|
||||||
@@ -60,6 +62,11 @@ notification_driver = messagingv2
|
|||||||
notification_topics = notifications,vitrage_notifications
|
notification_topics = notifications,vitrage_notifications
|
||||||
notification_driver = messagingv2
|
notification_driver = messagingv2
|
||||||
|
|
||||||
|
[[post-config|\$HEAT_CONF]]
|
||||||
|
[DEFAULT]
|
||||||
|
notification_topics = notifications,vitrage_notifications
|
||||||
|
notification_driver = messagingv2
|
||||||
|
|
||||||
[[post-config|\$VITRAGE_CONF]]
|
[[post-config|\$VITRAGE_CONF]]
|
||||||
[static_physical]
|
[static_physical]
|
||||||
changes_interval = 5
|
changes_interval = 5
|
||||||
|
|||||||
@@ -143,6 +143,11 @@ function configure_vitrage {
|
|||||||
disable_vitrage_datasource aodh
|
disable_vitrage_datasource aodh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# remove heat vitrage datasource if heat datasource not installed
|
||||||
|
if ! is_service_enabled heat; then
|
||||||
|
disable_vitrage_datasource heat.stack
|
||||||
|
fi
|
||||||
|
|
||||||
# remove nagios vitrage datasource if nagios datasource not installed
|
# remove nagios vitrage datasource if nagios datasource not installed
|
||||||
if [ "$VITRAGE_USE_NAGIOS" == "False" ]; then
|
if [ "$VITRAGE_USE_NAGIOS" == "False" ]; then
|
||||||
disable_vitrage_datasource nagios
|
disable_vitrage_datasource nagios
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ fi
|
|||||||
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/devstack/files/tempest/tempest.conf /etc/tempest.conf')
|
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/devstack/files/tempest/tempest.conf /etc/tempest.conf')
|
||||||
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/vitrage_tempest_tests/tests/resources/static_physical/static_physical_configuration.yaml /etc/vitrage/')
|
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/vitrage_tempest_tests/tests/resources/static_physical/static_physical_configuration.yaml /etc/vitrage/')
|
||||||
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/vitrage_tempest_tests/tests/resources/templates/api/* /etc/vitrage/templates/')
|
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/vitrage_tempest_tests/tests/resources/templates/api/* /etc/vitrage/templates/')
|
||||||
|
(cd $DEVSTACK_PATH/; sudo sh -c 'cp -rf vitrage/vitrage_tempest_tests/tests/resources/heat_templates/heat_template.yaml /etc/vitrage/')
|
||||||
|
|
||||||
|
|
||||||
sudo cp $DEVSTACK_PATH/tempest/etc/logging.conf.sample $DEVSTACK_PATH/tempest/etc/logging.conf
|
sudo cp $DEVSTACK_PATH/tempest/etc/logging.conf.sample $DEVSTACK_PATH/tempest/etc/logging.conf
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ VITRAGE_USE_MOD_WSGI=${VITRAGE_USE_MOD_WSGI:-${ENABLE_HTTPD_MOD_WSGI_SERVICES}}
|
|||||||
# Toggle for deploying Vitrage with/without nagios
|
# Toggle for deploying Vitrage with/without nagios
|
||||||
VITRAGE_USE_NAGIOS=$(trueorfalse False VITRAGE_USE_NAGIOS)
|
VITRAGE_USE_NAGIOS=$(trueorfalse False VITRAGE_USE_NAGIOS)
|
||||||
|
|
||||||
VITRAGE_DEFAULT_DATASOURCES=${VITRAGE_DEFAULT_DATASOURCES:-nova.host,nova.instance,nova.zone,nagios,static_physical,aodh,cinder.volume,neutron.network,neutron.port}
|
VITRAGE_DEFAULT_DATASOURCES=${VITRAGE_DEFAULT_DATASOURCES:-nova.host,nova.instance,nova.zone,nagios,static_physical,aodh,cinder.volume,neutron.network,neutron.port,heat.stack}
|
||||||
|
|
||||||
|
|
||||||
# Tell Tempest this project is present
|
# Tell Tempest this project is present
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class BaseAlarmsTest(BaseApiTest):
|
|||||||
self.ceilometer_client.alarms.create(**aodh_request)
|
self.ceilometer_client.alarms.create(**aodh_request)
|
||||||
self._wait_for_status(20,
|
self._wait_for_status(20,
|
||||||
self._check_num_alarms,
|
self._check_num_alarms,
|
||||||
num_alarms=1)
|
num_alarms=1,
|
||||||
|
state='alarm')
|
||||||
time.sleep(25)
|
time.sleep(25)
|
||||||
|
|
||||||
def _delete_ceilometer_alarms(self):
|
def _delete_ceilometer_alarms(self):
|
||||||
@@ -63,7 +64,7 @@ class BaseAlarmsTest(BaseApiTest):
|
|||||||
if resource_id:
|
if resource_id:
|
||||||
query = [
|
query = [
|
||||||
dict(
|
dict(
|
||||||
field=u'resource_id',
|
field=u'traits.resource_id',
|
||||||
type='',
|
type='',
|
||||||
op=u'eq',
|
op=u'eq',
|
||||||
value=resource_id)
|
value=resource_id)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from vitrage.common.constants import EntityCategory
|
|||||||
from vitrage.common.constants import VertexProperties as VProps
|
from vitrage.common.constants import VertexProperties as VProps
|
||||||
from vitrage.datasources import AODH_DATASOURCE
|
from vitrage.datasources import AODH_DATASOURCE
|
||||||
from vitrage.datasources import CINDER_VOLUME_DATASOURCE
|
from vitrage.datasources import CINDER_VOLUME_DATASOURCE
|
||||||
|
from vitrage.datasources.heat.stack import HEAT_STACK_DATASOURCE
|
||||||
from vitrage.datasources.neutron.network import NEUTRON_NETWORK_DATASOURCE
|
from vitrage.datasources.neutron.network import NEUTRON_NETWORK_DATASOURCE
|
||||||
from vitrage.datasources.neutron.port import NEUTRON_PORT_DATASOURCE
|
from vitrage.datasources.neutron.port import NEUTRON_PORT_DATASOURCE
|
||||||
from vitrage.datasources import NOVA_HOST_DATASOURCE
|
from vitrage.datasources import NOVA_HOST_DATASOURCE
|
||||||
@@ -57,6 +58,7 @@ class BaseApiTest(base.BaseTestCase):
|
|||||||
cls.nova_client = clients.nova_client(cls.conf)
|
cls.nova_client = clients.nova_client(cls.conf)
|
||||||
cls.cinder_client = clients.cinder_client(cls.conf)
|
cls.cinder_client = clients.cinder_client(cls.conf)
|
||||||
cls.neutron_client = clients.neutron_client(cls.conf)
|
cls.neutron_client = clients.neutron_client(cls.conf)
|
||||||
|
cls.heat_client = clients.heat_client(cls.conf)
|
||||||
|
|
||||||
cls.num_default_networks = \
|
cls.num_default_networks = \
|
||||||
len(cls.neutron_client.list_networks()['networks'])
|
len(cls.neutron_client.list_networks()['networks'])
|
||||||
@@ -217,7 +219,7 @@ class BaseApiTest(base.BaseTestCase):
|
|||||||
return True
|
return True
|
||||||
count += 1
|
count += 1
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
LOG.info("wait_for_status - False ")
|
LOG.info("wait_for_status - False")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _entities_validation_data(self, **kwargs):
|
def _entities_validation_data(self, **kwargs):
|
||||||
@@ -300,6 +302,15 @@ class BaseApiTest(base.BaseTestCase):
|
|||||||
'port_edges', 0)}
|
'port_edges', 0)}
|
||||||
validation_data.append(props)
|
validation_data.append(props)
|
||||||
|
|
||||||
|
# heat.stack
|
||||||
|
props = {VProps.CATEGORY: EntityCategory.RESOURCE,
|
||||||
|
VProps.TYPE: HEAT_STACK_DATASOURCE,
|
||||||
|
self.NUM_VERTICES_PER_TYPE: kwargs.get(
|
||||||
|
'stack_entities', 0),
|
||||||
|
self.NUM_EDGES_PER_TYPE: kwargs.get(
|
||||||
|
'stack_edges', 0)}
|
||||||
|
validation_data.append(props)
|
||||||
|
|
||||||
return validation_data
|
return validation_data
|
||||||
|
|
||||||
def _validate_graph_correctness(self,
|
def _validate_graph_correctness(self,
|
||||||
@@ -322,14 +333,14 @@ class BaseApiTest(base.BaseTestCase):
|
|||||||
vertices = graph.get_vertices(vertex_attr_filter=query)
|
vertices = graph.get_vertices(vertex_attr_filter=query)
|
||||||
self.assertEqual(entity[self.NUM_VERTICES_PER_TYPE],
|
self.assertEqual(entity[self.NUM_VERTICES_PER_TYPE],
|
||||||
len(vertices),
|
len(vertices),
|
||||||
'%s%s' % ('Num vertices is incorrect for: %s',
|
'%s%s' % ('Num vertices is incorrect for: ',
|
||||||
entity[VProps.TYPE]))
|
entity[VProps.TYPE]))
|
||||||
|
|
||||||
num_edges = sum([len(graph.get_edges(vertex.vertex_id))
|
num_edges = sum([len(graph.get_edges(vertex.vertex_id))
|
||||||
for vertex in vertices])
|
for vertex in vertices])
|
||||||
self.assertEqual(entity[self.NUM_EDGES_PER_TYPE],
|
self.assertEqual(entity[self.NUM_EDGES_PER_TYPE],
|
||||||
num_edges,
|
num_edges,
|
||||||
'%s%s' % ('Num edges is incorrect for: %s',
|
'%s%s' % ('Num edges is incorrect for: ',
|
||||||
entity[VProps.TYPE]))
|
entity[VProps.TYPE]))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
104
vitrage_tempest_tests/tests/api/datasources/test_heat_stack.py
Normal file
104
vitrage_tempest_tests/tests/api/datasources/test_heat_stack.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# Copyright 2016 - Nokia
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
import time
|
||||||
|
|
||||||
|
from vitrage_tempest_tests.tests.api.topology.base import BaseTopologyTest
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TestHeatStack(BaseTopologyTest):
|
||||||
|
NUM_STACKS = 1
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(TestHeatStack, cls).setUpClass()
|
||||||
|
|
||||||
|
def test_heat_stack(self):
|
||||||
|
"""heat stack test
|
||||||
|
|
||||||
|
This test validate correctness topology graph with heat stack module
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Action
|
||||||
|
self._create_stacks(num_stacks=self.NUM_STACKS)
|
||||||
|
|
||||||
|
# Calculate expected results
|
||||||
|
api_graph = self.vitrage_client.topology.get()
|
||||||
|
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||||
|
entities = self._entities_validation_data(
|
||||||
|
host_entities=1,
|
||||||
|
host_edges=1 + self.NUM_STACKS,
|
||||||
|
instance_entities=self.NUM_STACKS,
|
||||||
|
instance_edges=3 * self.NUM_STACKS,
|
||||||
|
network_entities=self.num_default_networks,
|
||||||
|
network_edges=self.num_default_ports + self.NUM_STACKS,
|
||||||
|
port_entities=self.num_default_ports + self.NUM_STACKS,
|
||||||
|
port_edges=self.num_default_ports + 2 * self.NUM_STACKS,
|
||||||
|
stack_entities=self.NUM_STACKS,
|
||||||
|
stack_edges=self.NUM_STACKS)
|
||||||
|
num_entities = self.num_default_entities + 3 * self.NUM_STACKS + \
|
||||||
|
self.num_default_networks + self.num_default_ports
|
||||||
|
num_edges = self.num_default_edges + 4 * self.NUM_STACKS + \
|
||||||
|
self.num_default_ports
|
||||||
|
|
||||||
|
# Test Assertions
|
||||||
|
self._validate_graph_correctness(graph,
|
||||||
|
num_entities,
|
||||||
|
num_edges,
|
||||||
|
entities)
|
||||||
|
finally:
|
||||||
|
self._delete_stacks()
|
||||||
|
|
||||||
|
def _create_stacks(self, num_stacks):
|
||||||
|
with open('/etc/vitrage/heat_template.yaml', 'rb') as f:
|
||||||
|
template_data = f.read()
|
||||||
|
|
||||||
|
for i in range(num_stacks):
|
||||||
|
self.heat_client.stacks.create(stack_name='stack_%s' % i,
|
||||||
|
template=template_data,
|
||||||
|
parameters={})
|
||||||
|
self._wait_for_status(45,
|
||||||
|
self._check_num_stacks,
|
||||||
|
num_stacks=num_stacks,
|
||||||
|
state='CREATE_COMPLETE')
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
def _delete_stacks(self):
|
||||||
|
stacks = self.heat_client.stacks.list()
|
||||||
|
for stack in stacks:
|
||||||
|
try:
|
||||||
|
self.heat_client.stacks.delete(stack.__dict__['id'])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self._wait_for_status(30,
|
||||||
|
self._check_num_stacks,
|
||||||
|
num_stacks=0)
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
def _check_num_stacks(self, num_stacks, state=''):
|
||||||
|
stacks_list = \
|
||||||
|
[stack.__dict__ for stack in self.heat_client.stacks.list()
|
||||||
|
if 'FAILED' not in stack.__dict__['stack_status']]
|
||||||
|
if len(stacks_list) != num_stacks:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return all(stack['stack_status'].upper() == state.upper()
|
||||||
|
for stack in stacks_list)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
heat_template_version: 2013-05-23
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The heat template is used to demo
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
image:
|
||||||
|
type: string
|
||||||
|
default: cirros-0.3.4-x86_64-uec
|
||||||
|
network:
|
||||||
|
type: string
|
||||||
|
default: public
|
||||||
|
flavor:
|
||||||
|
type: string
|
||||||
|
default: m1.small
|
||||||
|
|
||||||
|
resources:
|
||||||
|
server_2:
|
||||||
|
type: OS::Nova::Server
|
||||||
|
properties:
|
||||||
|
image: { get_param: image }
|
||||||
|
flavor: { get_param: flavor }
|
||||||
|
networks:
|
||||||
|
- network: { get_param: network }
|
||||||
Reference in New Issue
Block a user