Porting tests from Amulet to Zaza and support for Python 3.8

Zaza tests can be found here:
https://github.com/openstack-charmers/zaza-openstack-tests/pull/59
https://github.com/openstack-charmers/zaza-openstack-tests/pull/185

Support Python 3.8 by pulling a version of charm-helpers containing https://github.com/juju/charm-helpers/pull/423

Func-Test-PR: https://github.com/openstack-charmers/zaza-openstack-tests/pull/185
Closes-Bug: #1828424

Change-Id: I844836b0c2f7556da0b73a7917b8ec18052ba841
This commit is contained in:
Eduardo Sousa 2019-09-24 16:34:35 +01:00 committed by Aurelien Lourot
parent 08ed5de953
commit bbf4ad60dd
31 changed files with 1503 additions and 1047 deletions

View File

@ -1,5 +1,5 @@
#!/usr/bin/make
PYTHON := /usr/bin/env python
PYTHON := /usr/bin/env python3
clean:
rm -rf .coverage .tox .testrepository trusty .unit-state.db
@ -10,11 +10,11 @@ lint:
test:
@# Bundletester expects unit tests here.
@tox -e py27
@tox -e py37
functional_test:
@echo Starting functional tests...
@tox -e func27
@echo Starting Zaza functional tests...
@tox -e func
bin/charm_helpers_sync.py:
@mkdir -p bin

View File

@ -17,7 +17,6 @@ import contextlib
import os
import six
import shutil
import sys
import yaml
import zipfile
@ -531,7 +530,7 @@ def clean_policyd_dir_for(service, keep_paths=None, user=None, group=None):
hookenv.log("Cleaning path: {}".format(path), level=hookenv.DEBUG)
if not os.path.exists(path):
ch_host.mkdir(path, owner=_user, group=_group, perms=0o775)
_scanner = os.scandir if sys.version_info > (3, 4) else _py2_scandir
_scanner = os.scandir if hasattr(os, 'scandir') else _fallback_scandir
for direntry in _scanner(path):
# see if the path should be kept.
if direntry.path in keep_paths:
@ -560,23 +559,25 @@ def maybe_create_directory_for(path, user, group):
@contextlib.contextmanager
def _py2_scandir(path):
"""provide a py2 implementation of os.scandir if this module ever gets used
in a py2 charm (unlikely). uses os.listdir() to get the names in the path,
and then mocks the is_dir() function using os.path.isdir() to check for a
def _fallback_scandir(path):
"""Fallback os.scandir implementation.
provide a fallback implementation of os.scandir if this module ever gets
used in a py2 or py34 charm. Uses os.listdir() to get the names in the path,
and then mocks the is_dir() function using os.path.isdir() to check for
directory.
:param path: the path to list the directories for
:type path: str
:returns: Generator that provides _P27Direntry objects
:rtype: ContextManager[_P27Direntry]
:returns: Generator that provides _FBDirectory objects
:rtype: ContextManager[_FBDirectory]
"""
for f in os.listdir(path):
yield _P27Direntry(f)
yield _FBDirectory(f)
class _P27Direntry(object):
"""Mock a scandir Direntry object with enough to use in
class _FBDirectory(object):
"""Mock a scandir Directory object with enough to use in
clean_policyd_dir_for
"""

View File

@ -278,7 +278,7 @@ PACKAGE_CODENAMES = {
('14', 'rocky'),
('15', 'stein'),
('16', 'train'),
('17', 'ussuri'),
('18', 'ussuri'),
]),
'ceilometer-common': OrderedDict([
('5', 'liberty'),
@ -326,7 +326,7 @@ PACKAGE_CODENAMES = {
('14', 'rocky'),
('15', 'stein'),
('16', 'train'),
('17', 'ussuri'),
('18', 'ussuri'),
]),
}
@ -555,9 +555,8 @@ def reset_os_release():
_os_rel = None
def os_release(package, base=None, reset_cache=False):
'''
Returns OpenStack release codename from a cached global.
def os_release(package, base=None, reset_cache=False, source_key=None):
"""Returns OpenStack release codename from a cached global.
If reset_cache then unset the cached os_release version and return the
freshly determined version.
@ -565,7 +564,20 @@ def os_release(package, base=None, reset_cache=False):
If the codename can not be determined from either an installed package or
the installation source, the earliest release supported by the charm should
be returned.
'''
:param package: Name of package to determine release from
:type package: str
:param base: Fallback codename if endavours to determine from package fail
:type base: Optional[str]
:param reset_cache: Reset any cached codename value
:type reset_cache: bool
:param source_key: Name of source configuration option
(default: 'openstack-origin')
:type source_key: Optional[str]
:returns: OpenStack release codename
:rtype: str
"""
source_key = source_key or 'openstack-origin'
if not base:
base = UBUNTU_OPENSTACK_RELEASE[lsb_release()['DISTRIB_CODENAME']]
global _os_rel
@ -575,7 +587,7 @@ def os_release(package, base=None, reset_cache=False):
return _os_rel
_os_rel = (
get_os_codename_package(package, fatal=False) or
get_os_codename_install_source(config('openstack-origin')) or
get_os_codename_install_source(config(source_key)) or
base)
return _os_rel
@ -658,6 +670,93 @@ def config_value_changed(option):
return current != saved
def get_endpoint_key(service_name, relation_id, unit_name):
"""Return the key used to refer to an ep changed notification from a unit.
:param service_name: Service name eg nova, neutron, placement etc
:type service_name: str
:param relation_id: The id of the relation the unit is on.
:type relation_id: str
:param unit_name: The name of the unit publishing the notification.
:type unit_name: str
:returns: The key used to refer to an ep changed notification from a unit
:rtype: str
"""
return '{}-{}-{}'.format(
service_name,
relation_id.replace(':', '_'),
unit_name.replace('/', '_'))
def get_endpoint_notifications(service_names, rel_name='identity-service'):
"""Return all notifications for the given services.
:param service_names: List of service name.
:type service_name: List
:param rel_name: Name of the relation to query
:type rel_name: str
:returns: A dict containing the source of the notification and its nonce.
:rtype: Dict[str, str]
"""
notifications = {}
for rid in relation_ids(rel_name):
for unit in related_units(relid=rid):
ep_changed_json = relation_get(
rid=rid,
unit=unit,
attribute='ep_changed')
if ep_changed_json:
ep_changed = json.loads(ep_changed_json)
for service in service_names:
if ep_changed.get(service):
key = get_endpoint_key(service, rid, unit)
notifications[key] = ep_changed[service]
return notifications
def endpoint_changed(service_name, rel_name='identity-service'):
"""Whether a new notification has been recieved for an endpoint.
:param service_name: Service name eg nova, neutron, placement etc
:type service_name: str
:param rel_name: Name of the relation to query
:type rel_name: str
:returns: Whether endpoint has changed
:rtype: bool
"""
changed = False
with unitdata.HookData()() as t:
db = t[0]
notifications = get_endpoint_notifications(
[service_name],
rel_name=rel_name)
for key, nonce in notifications.items():
if db.get(key) != nonce:
juju_log(('New endpoint change notification found: '
'{}={}').format(key, nonce),
'INFO')
changed = True
break
return changed
def save_endpoint_changed_triggers(service_names, rel_name='identity-service'):
"""Save the enpoint triggers in db so it can be tracked if they changed.
:param service_names: List of service name.
:type service_name: List
:param rel_name: Name of the relation to query
:type rel_name: str
"""
with unitdata.HookData()() as t:
db = t[0]
notifications = get_endpoint_notifications(
service_names,
rel_name=rel_name)
for key, nonce in notifications.items():
db.set(key, nonce)
def save_script_rc(script_path="scripts/scriptrc", **env_vars):
"""
Write an rc file in the charm-delivered directory containing

View File

@ -37,7 +37,19 @@ class VaultKVContext(context.OSContextGenerator):
)
def __call__(self):
import hvac
try:
import hvac
except ImportError:
# BUG: #1862085 - if the relation is made to vault, but the
# 'encrypt' option is not made, then the charm errors with an
# import warning. This catches that, logs a warning, and returns
# with an empty context.
hookenv.log("VaultKVContext: trying to use hvac pythong module "
"but it's not available. Is secrets-stroage relation "
"made, but encrypt option not set?",
level=hookenv.WARNING)
# return an emptry context on hvac import error
return {}
ctxt = {}
# NOTE(hopem): see https://bugs.launchpad.net/charm-helpers/+bug/1849323
db = unitdata.kv()

View File

@ -1042,7 +1042,7 @@ def filesystem_mounted(fs):
def make_filesystem(blk_device, fstype='ext4', timeout=10):
"""Make a new filesystem on the specified block device."""
count = 0
e_noent = os.errno.ENOENT
e_noent = errno.ENOENT
while not os.path.exists(blk_device):
if count >= timeout:
log('Gave up waiting on block device %s' % blk_device,

View File

@ -25,6 +25,7 @@ UBUNTU_RELEASES = (
'cosmic',
'disco',
'eoan',
'focal'
)

View File

@ -1,4 +1,5 @@
import platform
import os
def get_platform():
@ -9,9 +10,13 @@ def get_platform():
This string is used to decide which platform module should be imported.
"""
# linux_distribution is deprecated and will be removed in Python 3.7
# Warings *not* disabled, as we certainly need to fix this.
tuple_platform = platform.linux_distribution()
current_platform = tuple_platform[0]
# Warnings *not* disabled, as we certainly need to fix this.
if hasattr(platform, 'linux_distribution'):
tuple_platform = platform.linux_distribution()
current_platform = tuple_platform[0]
else:
current_platform = _get_platform_from_fs()
if "Ubuntu" in current_platform:
return "ubuntu"
elif "CentOS" in current_platform:
@ -26,3 +31,16 @@ def get_platform():
else:
raise RuntimeError("This module is not supported on {}."
.format(current_platform))
def _get_platform_from_fs():
"""Get Platform from /etc/os-release."""
with open(os.path.join(os.sep, 'etc', 'os-release')) as fin:
content = dict(
line.split('=', 1)
for line in fin.read().splitlines()
if '=' in line
)
for k, v in content.items():
content[k] = v.strip('"')
return content["NAME"]

View File

@ -7,23 +7,8 @@ mock>=1.2
flake8>=2.2.4,<=2.4.1
stestr>=2.2.0
requests>=2.18.4
# BEGIN: Amulet OpenStack Charm Helper Requirements
# Liberty client lower constraints
amulet>=1.14.3,<2.0;python_version=='2.7'
bundletester>=0.6.1,<1.0;python_version=='2.7'
python-ceilometerclient>=1.5.0
python-cinderclient>=1.4.0,<5.0.0
python-glanceclient>=1.1.0
python-heatclient>=0.8.0
python-keystoneclient>=1.7.1
python-neutronclient>=3.1.0
python-novaclient>=2.30.1
python-openstackclient>=1.7.0
python-swiftclient>=2.6.0
pika>=0.10.0,<1.0
distro-info
git+https://github.com/juju/charm-helpers.git#egg=charmhelpers
# END: Amulet OpenStack Charm Helper Requirements
# NOTE: workaround for 14.04 pip/tox
pytz
pyudev # for ceph-* charm unit tests (not mocked?)
git+https://github.com/openstack-charmers/zaza.git#egg=zaza;python_version>='3.0'
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack

View File

@ -1,9 +0,0 @@
# Overview
This directory provides Amulet tests to verify basic deployment functionality
from the perspective of this charm, its requirements and its features, as
exercised in a subset of the full OpenStack deployment test bundle topology.
For full details on functional testing of OpenStack charms please refer to
the [functional testing](http://docs.openstack.org/developer/charm-guide/testing.html#functional-testing)
section of the OpenStack Charm Guide.

View File

@ -1,724 +0,0 @@
# Copyright 2016 Canonical Ltd
#
# 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 amulet
import ceilometerclient.v2.client as ceilo_client
from charmhelpers.contrib.openstack.amulet.deployment import (
OpenStackAmuletDeployment
)
from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils,
DEBUG,
# ERROR
)
# Use DEBUG to turn on debug logging
u = OpenStackAmuletUtils(DEBUG)
class CeilometerBasicDeployment(OpenStackAmuletDeployment):
"""Amulet tests on a basic ceilometer deployment."""
no_origin = ['memcached', 'percona-cluster', 'rabbitmq-server',
'ceph-mon', 'ceph-osd']
def __init__(self, series, openstack=None, source=None, stable=False):
"""Deploy the entire test environment."""
super(CeilometerBasicDeployment, self).__init__(series, openstack,
source, stable)
self._add_services()
self._add_relations()
self._configure_services()
self._deploy()
u.log.info('Waiting on extended status checks...')
self.exclude_services = ['mongodb', 'memcached']
if self._get_openstack_release() >= self.xenial_pike:
# Ceilometer will come up blocked until the ceilometer-upgrade
# action is run
self.exclude_services.append("ceilometer")
self._auto_wait_for_status(exclude_services=self.exclude_services)
self.d.sentry.wait()
self._initialize_tests()
def _add_services(self):
"""Add services
Add the services that we're testing, where ceilometer is local,
and the rest of the service are from lp branches that are
compatible with the local charm (e.g. stable or next).
"""
# Note: Revert back to cs:mongodb when it supports current UCA pockets
# https://bugs.launchpad.net/charm-ceilometer/+bug/1671865
this_service = {'name': 'ceilometer'}
other_services = [
self.get_percona_service_entry(),
{'name': 'rabbitmq-server'},
{'name': 'keystone'},
{'name': 'glance'}, # to satisfy workload status
{'name': 'ceilometer-agent'},
{'name': 'nova-compute'},
{'name': 'nova-cloud-controller'},
]
if self._get_openstack_release() >= self.xenial_pike:
other_services.extend([
{'name': 'gnocchi'},
{'name': 'memcached',
'location': 'cs:~memcached-team/memcached'},
{'name': 'ceph-mon', 'units': 3},
{'name': 'ceph-osd', 'units': 3,
'storage': {'osd-devices': 'cinder,10G'}}])
else:
other_services.append({
'name': 'mongodb',
'location': 'cs:~thedac/{}/mongodb'.format(self.series)})
if self._get_openstack_release() >= self.bionic_train:
other_train_services = [
{'name': 'placement'},
]
other_services += other_train_services
super(CeilometerBasicDeployment, self)._add_services(
this_service,
other_services,
no_origin=self.no_origin)
def _add_relations(self):
"""Add all of the relations for the services."""
relations = {
'ceilometer:amqp': 'rabbitmq-server:amqp',
'ceilometer:identity-notifications': 'keystone:'
'identity-notifications',
'keystone:shared-db': 'percona-cluster:shared-db',
'ceilometer:ceilometer-service': 'ceilometer-agent:'
'ceilometer-service',
'ceilometer-agent:amqp': 'rabbitmq-server:amqp',
'nova-compute:nova-ceilometer': 'ceilometer-agent:nova-ceilometer',
'nova-compute:amqp': 'rabbitmq-server:amqp',
'glance:identity-service': 'keystone:identity-service',
'glance:shared-db': 'percona-cluster:shared-db',
'glance:amqp': 'rabbitmq-server:amqp',
'nova-compute:image-service': 'glance:image-service',
'nova-cloud-controller:shared-db': 'percona-cluster:shared-db',
'nova-cloud-controller:amqp': 'rabbitmq-server:amqp',
'nova-cloud-controller:identity-service': 'keystone:'
'identity-service',
'nova-cloud-controller:cloud-compute': 'nova-compute:'
'cloud-compute',
'nova-cloud-controller:image-service': 'glance:image-service',
}
if self._get_openstack_release() >= self.xenial_pike:
additional_relations = {
'ceilometer:metric-service': 'gnocchi:metric-service',
'ceph-mon:osd': 'ceph-osd:mon',
'gnocchi:identity-service': 'keystone:identity-service',
'gnocchi:shared-db': 'percona-cluster:shared-db',
'gnocchi:storage-ceph': 'ceph-mon:client',
'gnocchi:coordinator-memcached': 'memcached:cache',
}
if self._get_openstack_release() >= self.xenial_queens:
identity_relations = {'ceilometer:identity-credentials':
'keystone:identity-credentials'}
else:
identity_relations = {'ceilometer:identity-service':
'keystone:identity-service'}
additional_relations.update(identity_relations)
else:
additional_relations = {
'ceilometer:shared-db': 'mongodb:database',
'ceilometer:identity-service': 'keystone:identity-service'}
relations.update(additional_relations)
if self._get_openstack_release() >= self.bionic_train:
train_relations = {
'placement:shared-db': 'percona-cluster:shared-db',
'placement:identity-service': 'keystone:identity-service',
'placement:placement': 'nova-cloud-controller:placement',
}
relations.update(train_relations)
super(CeilometerBasicDeployment, self)._add_relations(relations)
def _configure_services(self):
"""Configure all of the services."""
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
pxc_config = {
'dataset-size': '25%',
'max-connections': 1000,
'root-password': 'ChangeMe123',
'sst-password': 'ChangeMe123',
}
placement_config = {}
configs = {
'keystone': keystone_config,
'percona-cluster': pxc_config,
}
if self._get_openstack_release() >= self.bionic_train:
configs['placement'] = placement_config
super(CeilometerBasicDeployment, self)._configure_services(configs)
def _get_token(self):
return self.keystone.service_catalog.catalog['token']['id']
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
self.ceil_sentry = self.d.sentry['ceilometer'][0]
self.ceil_agent_sentry = self.d.sentry['ceilometer-agent'][0]
self.pxc_sentry = self.d.sentry['percona-cluster'][0]
self.keystone_sentry = self.d.sentry['keystone'][0]
self.rabbitmq_sentry = self.d.sentry['rabbitmq-server'][0]
self.nova_sentry = self.d.sentry['nova-compute'][0]
if self._get_openstack_release() >= self.xenial_pike:
self.gnocchi_sentry = self.d.sentry['gnocchi'][0]
self.run_ceilometer_upgrade_action()
else:
self.mongodb_sentry = self.d.sentry['mongodb'][0]
u.log.debug('openstack release val: {}'.format(
self._get_openstack_release()))
u.log.debug('openstack release str: {}'.format(
self._get_openstack_release_string()))
# Authenticate admin with keystone endpoint
self.keystone_session, self.keystone = u.get_default_keystone_session(
self.keystone_sentry,
openstack_release=self._get_openstack_release())
self.log.debug('Instantiating ceilometer client...')
if self._get_openstack_release() >= self.xenial_pike:
self.ceil = ceilo_client.Client(session=self.keystone_session,)
else:
# Authenticate admin with ceilometer endpoint
ep = self.keystone.service_catalog.url_for(service_type='metering',
interface='publicURL')
os_token = self.keystone.auth_token
self.ceil = ceilo_client.Client(endpoint=ep, token=os_token)
def test_100_services(self):
"""Verify the expected services are running on the corresponding
service units."""
u.log.debug('Checking system services on units...')
release = self._get_openstack_release()
ceilometer_svcs = [
'ceilometer-agent-central',
'ceilometer-agent-notification',
]
if release < self.xenial_pike:
ceilometer_svcs.append('ceilometer-collector')
if (release >= self.xenial_ocata and release < self.xenial_pike):
ceilometer_svcs.append('apache2')
if release < self.xenial_ocata:
ceilometer_svcs.append('ceilometer-api')
if release < self.trusty_mitaka:
ceilometer_svcs.append('ceilometer-alarm-evaluator')
ceilometer_svcs.append('ceilometer-alarm-notifier')
service_names = {
self.ceil_sentry: ceilometer_svcs,
}
ret = u.validate_services_by_name(service_names)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
u.log.debug('OK')
def test_105_memcache(self):
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping memcache test as memcache server is external'
' to ceilometer')
return
u.validate_memcache(self.ceil_sentry,
'/etc/ceilometer/ceilometer.conf',
self._get_openstack_release(),
earliest_release=self.trusty_mitaka)
def test_110_service_catalog(self):
"""Verify that the service catalog endpoint data is valid."""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping catalogue checks as ceilometer no longer '
'registers endpoints')
return
u.log.debug('Checking keystone service catalog data...')
endpoint_check = {
'adminURL': u.valid_url,
'id': u.not_null,
'region': 'RegionOne',
'publicURL': u.valid_url,
'internalURL': u.valid_url
}
expected = {
'metering': [endpoint_check],
'identity': [endpoint_check]
}
actual = self.keystone.service_catalog.get_endpoints()
ret = u.validate_svc_catalog_endpoint_data(
expected,
actual,
openstack_release=self._get_openstack_release())
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
u.log.debug('OK')
def test_112_keystone_api_endpoint(self):
"""Verify the ceilometer api endpoint data."""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping catalogue checks as ceilometer no longer '
'registers endpoints')
return
u.log.debug('Checking keystone api endpoint data...')
endpoints = self.keystone.endpoints.list()
u.log.debug(endpoints)
internal_port = public_port = '5000'
admin_port = '35357'
expected = {'id': u.not_null,
'region': 'RegionOne',
'adminurl': u.valid_url,
'internalurl': u.valid_url,
'publicurl': u.valid_url,
'service_id': u.not_null}
ret = u.validate_endpoint_data(
endpoints,
admin_port,
internal_port,
public_port,
expected,
openstack_release=self._get_openstack_release())
if ret:
message = 'Keystone endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_114_ceilometer_api_endpoint(self):
"""Verify the ceilometer api endpoint data."""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping catalogue checks as ceilometer no longer '
'registers endpoints')
return
u.log.debug('Checking ceilometer api endpoint data...')
endpoints = self.keystone.endpoints.list()
u.log.debug(endpoints)
admin_port = internal_port = public_port = '8777'
expected = {'id': u.not_null,
'region': 'RegionOne',
'adminurl': u.valid_url,
'internalurl': u.valid_url,
'publicurl': u.valid_url,
'service_id': u.not_null}
ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
public_port, expected)
if ret:
message = 'Ceilometer endpoint: {}'.format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_200_ceilometer_identity_relation(self):
"""Verify the ceilometer to keystone identity-service relation data"""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping identity-service checks as ceilometer no '
'longer has this rerlation')
return
u.log.debug('Checking ceilometer to keystone identity-service '
'relation data...')
unit = self.ceil_sentry
relation = ['identity-service', 'keystone:identity-service']
ceil_ip = unit.relation('identity-service',
'keystone:identity-service')['private-address']
ceil_endpoint = "http://%s:8777" % (ceil_ip)
expected = {
'admin_url': ceil_endpoint,
'internal_url': ceil_endpoint,
'private-address': ceil_ip,
'public_url': ceil_endpoint,
'region': 'RegionOne',
'requested_roles': 'ResellerAdmin',
'service': 'ceilometer',
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_201_keystone_ceilometer_identity_relation(self):
"""Verify the keystone to ceilometer identity-service relation data"""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping identity-service checks as ceilometer no '
'longer has this rerlation')
return
u.log.debug('Checking keystone:ceilometer identity relation data...')
unit = self.keystone_sentry
relation = ['identity-service', 'ceilometer:identity-service']
id_relation = unit.relation('identity-service',
'ceilometer:identity-service')
id_ip = id_relation['private-address']
expected = {
'admin_token': 'ubuntutesting',
'auth_host': id_ip,
'auth_port': "35357",
'auth_protocol': 'http',
'private-address': id_ip,
'service_host': id_ip,
'service_password': u.not_null,
'service_port': "5000",
'service_protocol': 'http',
'service_tenant': 'services',
'service_tenant_id': u.not_null,
'service_username': 'ceilometer',
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('keystone identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_202_keystone_ceilometer_identity_notes_relation(self):
"""Verify ceilometer to keystone identity-notifications relation"""
u.log.debug('Checking keystone:ceilometer '
'identity-notifications relation data...')
# Relation data may vary depending on timing of hooks and relations.
# May be glance- or keystone- or another endpoint-changed value, so
# check that at least one ???-endpoint-changed value exists.
unit = self.keystone_sentry
relation_data = unit.relation('identity-notifications',
'ceilometer:identity-notifications')
expected = '-endpoint-changed'
found = 0
for key in relation_data.keys():
if expected in key and relation_data[key]:
found += 1
u.log.debug('{}: {}'.format(key, relation_data[key]))
if not found:
message = ('keystone:ceilometer identity-notification relation '
'error\n expected something like: {}\n actual: '
'{}'.format(expected, relation_data))
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_203_ceilometer_amqp_relation(self):
"""Verify the ceilometer to rabbitmq-server amqp relation data"""
u.log.debug('Checking ceilometer:rabbitmq amqp relation data...')
unit = self.ceil_sentry
relation = ['amqp', 'rabbitmq-server:amqp']
expected = {
'username': 'ceilometer',
'private-address': u.valid_ip,
'vhost': 'openstack'
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer amqp', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_204_amqp_ceilometer_relation(self):
"""Verify the rabbitmq-server to ceilometer amqp relation data"""
u.log.debug('Checking rabbitmq:ceilometer amqp relation data...')
unit = self.rabbitmq_sentry
relation = ['amqp', 'ceilometer:amqp']
expected = {
'hostname': u.valid_ip,
'private-address': u.valid_ip,
'password': u.not_null,
}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('rabbitmq amqp', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_207_ceilometer_ceilometer_agent_relation(self):
"""Verify the ceilometer to ceilometer-agent relation data"""
u.log.debug('Checking ceilometer:ceilometer-agent relation data...')
unit = self.ceil_sentry
relation = ['ceilometer-service',
'ceilometer-agent:ceilometer-service']
expected = {
'rabbitmq_user': 'ceilometer',
'verbose': 'False',
'rabbitmq_host': u.valid_ip,
'use_syslog': 'False',
'metering_secret': u.not_null,
'rabbitmq_virtual_host': 'openstack',
'private-address': u.valid_ip,
'debug': 'False',
'rabbitmq_password': u.not_null,
'port': '8767'
}
if self._get_openstack_release() >= self.xenial_pike:
expected['gnocchi_url'] = u.valid_url
if self._get_openstack_release() >= self.xenial_queens:
expected['port'] = '8777'
else:
expected['db_port'] = '27017'
expected['db_name'] = 'ceilometer'
expected['db_host'] = u.valid_ip
expected['service_ports'] = "{'ceilometer_api': [8777, 8767]}"
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_208_ceilometer_agent_ceilometer_relation(self):
"""Verify the ceilometer-agent to ceilometer relation data"""
u.log.debug('Checking ceilometer-agent:ceilometer relation data...')
unit = self.ceil_agent_sentry
relation = ['ceilometer-service', 'ceilometer:ceilometer-service']
expected = {'private-address': u.valid_ip}
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('ceilometer-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_300_ceilometer_config(self):
"""Verify the data in the ceilometer config file."""
u.log.debug('Checking ceilometer config file data...')
unit = self.ceil_sentry
conf = '/etc/ceilometer/ceilometer.conf'
expected = {
'DEFAULT': {
'verbose': 'False',
'debug': 'False',
'use_syslog': 'False',
},
'api': {
'port': '8767',
},
}
if self._get_openstack_release() >= self.xenial_pike:
relation = self.gnocchi_sentry.relation(
'metric-service',
'ceilometer:metric-service')
expected['dispatcher_gnocchi'] = {'url': relation['gnocchi_url']}
if self._get_openstack_release() >= self.xenial_queens:
ks_rel = self.keystone_sentry.relation(
'identity-credentials',
'ceilometer:identity-credentials')
ks_key_prefix = 'credentials'
else:
ks_rel = self.keystone_sentry.relation(
'identity-service',
'ceilometer:identity-service')
ks_key_prefix = 'service'
else:
db_relation = self.mongodb_sentry.relation('database',
'ceilometer:shared-db')
db_conn = 'mongodb://%s:%s/ceilometer' % (db_relation['hostname'],
db_relation['port'])
expected['database'] = {'connection': db_conn}
ks_rel = self.keystone_sentry.relation(
'identity-service',
'ceilometer:identity-service')
ks_key_prefix = 'service'
if self._get_openstack_release() < self.trusty_mitaka:
auth_uri = '%s://%s:%s/v2.0' % (ks_rel['service_protocol'],
ks_rel['service_host'],
ks_rel['service_port'])
expected['service_credentials'] = {'os_auth_url': auth_uri,
'os_tenant_name': 'services',
'os_username': 'ceilometer',
'os_password':
ks_rel['service_password']}
else:
auth_uri = '%s://%s:%s' % (
ks_rel['{}_protocol'.format(ks_key_prefix)],
ks_rel['{}_host'.format(ks_key_prefix)],
ks_rel['{}_port'.format(ks_key_prefix)])
# NOTE(dosaboy): os_ prefix is deprecated and no longer used as
# of Mitaka.
project_domain_name = 'default'
user_domain_name = 'default'
if 'api_version' in ks_rel and float(ks_rel['api_version']) > 2:
project_domain_name = 'service_domain'
user_domain_name = 'service_domain'
expected['service_credentials'] = {
'auth_url': auth_uri,
'project_name': 'services',
'project_domain_name': project_domain_name,
'user_domain_name': user_domain_name,
'username': 'ceilometer',
'password': ks_rel['{}_password'.format(ks_key_prefix)]}
if self._get_openstack_release() >= self.xenial_ocata:
del expected['api']
for section, pairs in expected.iteritems():
ret = u.validate_config_data(unit, conf, section, pairs)
if ret:
message = "ceilometer config error: {}".format(ret)
amulet.raise_status(amulet.FAIL, msg=message)
u.log.debug('OK')
def test_400_api_connection(self):
"""Simple api calls to check service is up and responding"""
if self._get_openstack_release() >= self.xenial_pike:
u.log.debug('Skipping API checks as ceilometer api has been '
'removed')
return
u.log.debug('Checking api functionality...')
assert(self.ceil.samples.list() == [])
assert(self.ceil.meters.list() == [])
u.log.debug('OK')
# NOTE(beisner): need to add more functional tests
def test_900_restart_on_config_change(self):
"""Verify that the specified services are restarted when the config
is changed.
"""
sentry = self.ceil_sentry
juju_service = 'ceilometer'
# Expected default and alternate values
set_default = {'debug': 'False'}
set_alternate = {'debug': 'True'}
# Services which are expected to restart upon config change,
# and corresponding config files affected by the change
conf_file = '/etc/ceilometer/ceilometer.conf'
if self._get_openstack_release() >= self.xenial_pike:
services = {
'ceilometer-polling: AgentManager worker(0)': conf_file,
'ceilometer-agent-notification: NotificationService worker(0)':
conf_file,
}
elif self._get_openstack_release() >= self.xenial_ocata:
services = {
'ceilometer-collector: CollectorService worker(0)': conf_file,
'ceilometer-polling: AgentManager worker(0)': conf_file,
'ceilometer-agent-notification: NotificationService worker(0)':
conf_file,
'apache2': conf_file,
}
elif self._get_openstack_release() >= self.xenial_newton:
services = {
'ceilometer-collector - CollectorService(0)': conf_file,
'ceilometer-polling - AgentManager(0)': conf_file,
'ceilometer-agent-notification - NotificationService(0)':
conf_file,
'ceilometer-api': conf_file,
}
else:
services = {
'ceilometer-collector': conf_file,
'ceilometer-api': conf_file,
'ceilometer-agent-notification': conf_file,
}
if self._get_openstack_release() < self.trusty_mitaka:
services['ceilometer-alarm-notifier'] = conf_file
services['ceilometer-alarm-evaluator'] = conf_file
if self._get_openstack_release() >= self.trusty_liberty:
# Liberty and later
services['ceilometer-polling'] = conf_file
else:
# Juno and earlier
services['ceilometer-agent-central'] = conf_file
# Make config change, check for service restarts
u.log.debug('Making config change on {}...'.format(juju_service))
mtime = u.get_sentry_time(sentry)
self.d.configure(juju_service, set_alternate)
sleep_time = 40
for s, conf_file in services.iteritems():
u.log.debug("Checking that service restarted: {}".format(s))
if not u.validate_service_config_changed(sentry, mtime, s,
conf_file,
retry_count=4,
retry_sleep_time=20,
sleep_time=sleep_time):
self.d.configure(juju_service, set_default)
msg = "service {} didn't restart after config change".format(s)
amulet.raise_status(amulet.FAIL, msg=msg)
sleep_time = 0
self.d.configure(juju_service, set_default)
u.log.debug('OK')
def test_910_pause_and_resume(self):
"""The services can be paused and resumed. """
u.log.debug('Checking pause and resume actions...')
unit = self.ceil_sentry
juju_service = 'ceilometer'
assert u.status_get(unit)[0] == "active"
action_id = unit.run_action("pause")
assert u.wait_on_action(action_id), "Pause action failed."
assert u.status_get(unit)[0] == "maintenance"
# trigger config-changed to ensure that services are still stopped
u.log.debug("Making config change on ceilometer ...")
self.d.configure(juju_service, {'debug': 'True'})
assert u.status_get(unit)[0] == "maintenance"
self.d.configure(juju_service, {'debug': 'False'})
assert u.status_get(unit)[0] == "maintenance"
action_id = unit.run_action("resume")
assert u.wait_on_action(action_id), "Resume action failed."
assert u.status_get(unit)[0] == "active"
u.log.debug('OK')
def run_ceilometer_upgrade_action(self):
"""Run ceilometer-upgrade
This action will be run early to initialize ceilometer
when gnocchi is related.
Ceilometer will be in a blocked state until this runs.
"""
if self._get_openstack_release() < self.xenial_pike:
u.log.debug('Not checking ceilometer-upgrade')
return
u.log.debug('Checking ceilometer-upgrade')
unit = self.ceil_sentry
action_id = unit.run_action("ceilometer-upgrade")
assert u.wait_on_action(action_id), "ceilometer-upgrade action failed"
# Wait for acivte Unit is ready on ceilometer
self.exclude_services.remove('ceilometer')
self._auto_wait_for_status(exclude_services=self.exclude_services)
u.log.debug('OK')

View File

@ -0,0 +1,130 @@
series: bionic
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
to:
- '12'
ceilometer:
num_units: 1
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,148 @@
options:
source: &source cloud:bionic-rocky
series: bionic
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
options:
source: *source
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *source
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '12'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
options:
openstack-origin: *source
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,148 @@
options:
source: &source cloud:bionic-stein
series: bionic
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
options:
source: *source
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *source
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '12'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
options:
openstack-origin: *source
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,148 @@
options:
source: &source cloud:bionic-train
series: bionic
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
options:
source: *source
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *source
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '12'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
options:
openstack-origin: *source
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,130 @@
series: disco
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
to:
- '12'
ceilometer:
num_units: 1
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,101 @@
options:
source: &source cloud:trusty-mitaka
series: trusty
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
applications:
percona-cluster:
charm: cs:trusty/percona-cluster
num_units: 1
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
mongodb:
charm: cs:trusty/mongodb
num_units: 1
to:
- '2'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '3'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '4'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '5'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '6'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '7'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:identity-service'
- 'keystone:identity-service'
- - 'ceilometer:shared-db'
- 'mongodb:database'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'

View File

@ -0,0 +1,89 @@
series: xenial
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
mongodb:
charm: cs:xenial/mongodb
num_units: 1
to:
- '2'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
to:
- '3'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
to:
- '4'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
to:
- '5'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
to:
- '6'
ceilometer:
num_units: 1
to:
- '7'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:identity-service'
- 'keystone:identity-service'
- - 'ceilometer:shared-db'
- 'mongodb:database'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'

View File

@ -0,0 +1,101 @@
options:
source: &source cloud:xenial-ocata
series: xenial
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
mongodb:
charm: cs:xenial/mongodb
num_units: 1
to:
- '2'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '3'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '4'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '5'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '6'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '7'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:identity-service'
- 'keystone:identity-service'
- - 'ceilometer:shared-db'
- 'mongodb:database'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'

View File

@ -0,0 +1,148 @@
options:
source: &source cloud:xenial-pike
series: xenial
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
options:
source: *source
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *source
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '12'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
options:
openstack-origin: *source
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-service'
- 'keystone:identity-service'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -0,0 +1,148 @@
options:
source: &source cloud:xenial-queens
series: xenial
machines:
0: {}
1: {}
2: {}
3: {}
4: {}
5: {}
6: {}
7: {}
8: {}
9: {}
10: {}
11: {}
12: {}
13: {}
14: {}
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
max-connections: 1000
innodb-buffer-pool-size: 256M
to:
- '0'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '1'
memcached:
charm: cs:~memcached-team/memcached
num_units: 1
to:
- '2'
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
num_units: 3
storage:
osd-devices: 'cinder,10G'
options:
source: *source
to:
- '3'
- '4'
- '5'
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *source
to:
- '6'
- '7'
- '8'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *source
to:
- '9'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *source
to:
- '10'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *source
to:
- '11'
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
options:
openstack-origin: *source
to:
- '12'
ceilometer:
num_units: 1
options:
openstack-origin: *source
to:
- '13'
gnocchi:
charm: cs:~openstack-charmers-next/gnocchi
num_units: 1
options:
openstack-origin: *source
to:
- '14'
ceilometer-agent:
charm: cs:~openstack-charmers-next/ceilometer-agent
relations:
- - 'ceilometer:amqp'
- 'rabbitmq-server:amqp'
- - 'ceilometer:identity-notifications'
- 'keystone:identity-notifications'
- - 'ceilometer:ceilometer-service'
- 'ceilometer-agent:ceilometer-service'
- - 'ceilometer:metric-service'
- 'gnocchi:metric-service'
- - 'ceilometer:identity-credentials'
- 'keystone:identity-credentials'
- - 'keystone:shared-db'
- 'percona-cluster:shared-db'
- - 'ceilometer-agent:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:nova-ceilometer'
- 'ceilometer-agent:nova-ceilometer'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'percona-cluster:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:shared-db'
- 'percona-cluster:shared-db'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'gnocchi:shared-db'
- 'percona-cluster:shared-db'
- - 'gnocchi:storage-ceph'
- 'ceph-mon:client'
- - 'gnocchi:coordinator-memcached'
- 'memcached:cache'
- - 'gnocchi:identity-service'
- 'keystone:identity-service'

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on bionic-queens."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='bionic')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on bionic-rocky."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='bionic',
openstack='cloud:bionic-rocky',
source='cloud:bionic-updates/rocky')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on bionic-stein."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='bionic',
openstack='cloud:bionic-stein',
source='cloud:bionic-stein')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2019 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on bionic-train."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='bionic',
openstack='cloud:bionic-train',
source='cloud:bionic-train')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on trusty-mitaka."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='trusty',
openstack='cloud:trusty-mitaka',
source='cloud:trusty-updates/mitaka')
deployment.run_tests()

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on xenial-mitaka."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='xenial')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on xenial-ocata."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='xenial',
openstack='cloud:xenial-ocata',
source='cloud:xenial-updates/ocata')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on xenial-pike."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='xenial',
openstack='cloud:xenial-pike',
source='cloud:xenial-updates/pike')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# 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.
"""Amulet tests on a basic ceilometer deployment on xenial-queens."""
from basic_deployment import CeilometerBasicDeployment
if __name__ == '__main__':
deployment = CeilometerBasicDeployment(series='xenial',
openstack='cloud:xenial-queens',
source='cloud:xenial-updates/queens')
deployment.run_tests()

View File

@ -1,18 +1,22 @@
# Bootstrap the model if necessary.
bootstrap: True
# Re-use bootstrap node.
reset: True
# Use tox/requirements to drive the venv instead of bundletester's venv feature.
virtualenv: False
# Leave makefile empty, otherwise unit/lint tests will rerun ahead of amulet.
makefile: []
# Do not specify juju PPA sources. Juju is presumed to be pre-installed
# and configured in all test runner environments.
#sources:
# Do not specify or rely on system packages.
#packages:
# Do not specify python packages here. Use test-requirements.txt
# and tox instead. ie. The venv is constructed before bundletester
# is invoked.
#python-packages:
reset_timeout: 600
charm_name: ceilometer
configure:
- zaza.openstack.charm_tests.ceilometer.setup.basic_setup
gate_bundles:
- trusty-mitaka
- xenial-mitaka
- xenial-ocata
- xenial-pike
- xenial-queens
- bionic-queens
- bionic-rocky
- bionic-stein
smoke_bundles:
- bionic-stein
dev_bundles:
- bionic-train
tests:
- zaza.openstack.charm_tests.ceilometer.tests.CeilometerTest
target_deploy_status:
ceilometer:
workload-status: blocked
workload-status-message: "Run the ceilometer-upgrade action on the leader to initialize ceilometer and gnocchi"

61
tox.ini
View File

@ -1,8 +1,12 @@
# Classic charm (with amulet): ./tox.ini
# Classic charm (with zaza): ./tox.ini
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
# TODO: Distill the func test requirements from the lint/unit test
# requirements. They are intertwined. Also, Zaza itself should specify
# all of its own requirements and if it doesn't, fix it there.
[tox]
envlist = pep8,py3
skipsdist = True
@ -15,17 +19,12 @@ skip_missing_interpreters = False
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
CHARM_DIR={envdir}
AMULET_SETUP_TIMEOUT=5400
install_command =
pip install {opts} {packages}
commands = stestr run --slowest {posargs}
whitelist_externals = juju
passenv = HOME TERM AMULET_* CS_* OS_* TEST_*
[testenv:py3]
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
passenv = HOME TERM CS_* OS_* TEST_*
deps = -r{toxinidir}/test-requirements.txt
[testenv:py35]
basepython = python3.5
@ -42,6 +41,16 @@ basepython = python3.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
[testenv:py38]
basepython = python3.8
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
[testenv:py3]
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
[testenv:pep8]
basepython = python3
deps = -r{toxinidir}/requirements.txt
@ -82,39 +91,29 @@ basepython = python3
commands = {posargs}
[testenv:func-noop]
# DRY RUN - For Debug
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
basepython = python3
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" -n --no-destroy
functest-run-suite --help
[testenv:func]
# Charm Functional Test
# Run all gate tests which are +x (expected to always pass)
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
basepython = python3
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" --no-destroy
functest-run-suite --keep-model
[testenv:func-smoke]
# Charm Functional Test
# Run a specific test as an Amulet smoke test (expected to always pass)
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
basepython = python3
commands =
bundletester -vl DEBUG -r json -o func-results.json gate-basic-bionic-train --no-destroy
functest-run-suite --keep-model --smoke
[testenv:func-dev]
# Charm Functional Test
# Run all development test targets which are +x (may not always pass!)
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
basepython = python3
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "dev-*" --no-destroy
functest-run-suite --keep-model --dev
[testenv:func-target]
basepython = python3
commands =
functest-run-suite --keep-model --bundle {posargs}
[flake8]
ignore = E402,E226