update amulet test

This commit is contained in:
Ryan Beisner 2015-08-01 02:34:37 +00:00
parent 189013a1eb
commit 6c29349c0c
5 changed files with 146 additions and 108 deletions

View File

@ -2,13 +2,20 @@
PYTHON := /usr/bin/env python
lint:
@flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests
@flake8 --exclude hooks/charmhelpers,tests/charmhelpers \
actions hooks unit_tests tests
@charm proof
unit_test:
test:
@# Bundletester expects unit tests here.
@echo Starting tests...
@$(PYTHON) /usr/bin/nosetests --nologcapture unit_tests
functional_test:
@echo Starting Amulet tests...
# https://bugs.launchpad.net/amulet/+bug/1320357
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
bin/charm_helpers_sync.py:
@mkdir -p bin
@bzr cat lp:charm-helpers/tools/charm_helpers_sync/charm_helpers_sync.py \
@ -18,13 +25,6 @@ sync: bin/charm_helpers_sync.py
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-tests.yaml
test:
@echo Starting Amulet tests...
# coreycb note: The -v should only be temporary until Amulet sends
# raise_status() messages to stderr:
# https://bugs.launchpad.net/amulet/+bug/1320357
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
publish: lint test
bzr push lp:charms/openstack-dashboard
bzr push lp:charms/trusty/openstack-dashboard

View File

@ -4,7 +4,9 @@ maintainer: Adam Gandelman <adamg@canonical.com>
description: |
The OpenStack Dashboard provides a full feature web interface for interacting
with instances, images, volumes and networks within an OpenStack deployment.
categories: ["misc"]
tags:
- openstack
- misc
provides:
nrpe-external-master:
interface: nrpe-external-master

View File

@ -5,8 +5,11 @@ set -ex
sudo add-apt-repository --yes ppa:juju/stable
sudo apt-get update --yes
sudo apt-get install --yes python-amulet \
python-cinderclient \
python-distro-info \
python-neutronclient \
python-glanceclient \
python-heatclient \
python-keystoneclient \
python-neutronclient \
python-novaclient \
python-glanceclient
python-swiftclient

0
tests/019-basic-vivid-kilo Normal file → Executable file
View File

View File

@ -12,8 +12,8 @@ from charmhelpers.contrib.openstack.amulet.deployment import (
from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils,
DEBUG, # flake8: noqa
ERROR
DEBUG,
#ERROR
)
# Use DEBUG to turn on debug logging
@ -26,8 +26,8 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
def __init__(self, series, openstack=None, source=None, git=False,
stable=False):
"""Deploy the entire test environment."""
super(OpenstackDashboardBasicDeployment, self).__init__(series, openstack,
source, stable)
super(OpenstackDashboardBasicDeployment,
self).__init__(series, openstack, source, stable)
self.git = git
self._add_services()
self._add_relations()
@ -38,22 +38,24 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
def _add_services(self):
"""Add services
Add the services that we're testing, where openstack-dashboard is local,
and the rest of the service are from lp branches that are
Add the services that we're testing, where openstack-dashboard
is local, and the rest of the service are from lp branches that are
compatible with the local charm (e.g. stable or next).
"""
this_service = {'name': 'openstack-dashboard'}
other_services = [{'name': 'keystone'}, {'name': 'mysql'}]
super(OpenstackDashboardBasicDeployment, self)._add_services(this_service,
other_services)
super(OpenstackDashboardBasicDeployment,
self)._add_services(this_service, other_services)
def _add_relations(self):
"""Add all of the relations for the services."""
relations = {
'openstack-dashboard:identity-service': 'keystone:identity-service',
'openstack-dashboard:identity-service':
'keystone:identity-service',
'keystone:shared-db': 'mysql:shared-db',
}
super(OpenstackDashboardBasicDeployment, self)._add_relations(relations)
super(OpenstackDashboardBasicDeployment,
self)._add_relations(relations)
def _configure_services(self):
"""Configure all of the services."""
@ -82,7 +84,8 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
'http_proxy': amulet_http_proxy,
'https_proxy': amulet_http_proxy,
}
horizon_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
horizon_config['openstack-origin-git'] = \
yaml.dump(openstack_origin_git)
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
@ -90,27 +93,22 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
configs = {'openstack-dashboard': horizon_config,
'mysql': mysql_config,
'keystone': keystone_config}
super(OpenstackDashboardBasicDeployment, self)._configure_services(configs)
super(OpenstackDashboardBasicDeployment,
self)._configure_services(configs)
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
self.keystone_sentry = self.d.sentry.unit['keystone/0']
self.openstack_dashboard_sentry = self.d.sentry.unit['openstack-dashboard/0']
self.openstack_dashboard_sentry = \
self.d.sentry.unit['openstack-dashboard/0']
def test_services(self):
"""Verify the expected services are running on the corresponding
service units."""
dashboard_services = ['service apache2 status']
commands = {
self.keystone_sentry: ['status keystone'],
self.openstack_dashboard_sentry: dashboard_services
}
ret = u.validate_services(commands)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
u.log.debug('openstack release val: {}'.format(
self._get_openstack_release()))
u.log.debug('openstack release str: {}'.format(
self._get_openstack_release_string()))
# Let things settle a bit before moving forward
time.sleep(30)
def crude_py_parse(self, file_contents, expected):
for line in file_contents.split('\n'):
@ -125,64 +123,23 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
msg = "Mismatch %s != %s" % (expected[key], value)
amulet.raise_status(amulet.FAIL, msg=msg)
def test_100_services(self):
"""Verify the expected services are running on the corresponding
service units."""
def test_local_settings(self):
unit = self.openstack_dashboard_sentry
ksentry = self.keystone_sentry
conf = '/etc/openstack-dashboard/local_settings.py'
file_contents = unit.file_contents(conf)
rdata = ksentry.relation('identity-service', 'openstack-dashboard:identity-service')
expected = {
'LOGIN_REDIRECT_URL': """'/horizon'""",
'OPENSTACK_HOST': '"%s"' % (rdata['private-address']),
'OPENSTACK_KEYSTONE_DEFAULT_ROLE': '"Member"'
services = {
self.keystone_sentry: ['keystone'],
self.openstack_dashboard_sentry: ['apache2']
}
self.crude_py_parse(file_contents, expected)
def test_router_settings(self):
if self.openstack > "icehouse":
unit = self.openstack_dashboard_sentry
conf = ('/usr/share/openstack-dashboard/openstack_dashboard/'
'enabled/_40_router.py')
file_contents = unit.file_contents(conf)
expected = {
'DISABLED': "True",
}
self.crude_py_parse(file_contents, expected)
ret = u.validate_services_by_name(services)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
def test_connection(self):
unit = self.openstack_dashboard_sentry
dashboard_relation = unit.relation('identity-service',
'keystone:identity-service')
dashboard_ip = dashboard_relation['private-address']
response = urllib2.urlopen('http://%s/horizon' % (dashboard_ip))
html = response.read()
if 'OpenStack Dashboard' not in html:
msg="Dashboard frontpage check failed"
amulet.raise_status(amulet.FAIL, msg=msg)
def test_z_restart_on_config_change(self):
"""Verify that the specified services are restarted when the config
is changed.
Note(coreycb): The method name with the _z_ is a little odd
but it forces the test to run last. It just makes things
easier because restarting services requires re-authorization.
"""
conf = '/etc/openstack-dashboard/local_settings.py'
services = ['apache2']
self.d.configure('openstack-dashboard', {'use-syslog': 'True'})
time = 120
for s in services:
if not u.service_restarted(self.openstack_dashboard_sentry, s, conf,
pgrep_full=True, sleep_time=time):
self.d.configure('openstack-dashboard', {'use-syslog': 'False'})
msg = "service {} didn't restart after config change".format(s)
time = 0
self.d.configure('openstack-dashboard', {'use-syslog': 'False'})
def test_openstack_dashboard_identity_service_relation(self):
"""Verify the openstack-dashboard to keystone identity-service relation data."""
def test_200_openstack_dashboard_identity_service_relation(self):
"""Verify the openstack-dashboard to keystone identity-service
relation data."""
u.log.debug('Checking dashboard:keystone id relation data...')
unit = self.openstack_dashboard_sentry
relation = ['identity-service', 'keystone:identity-service']
expected = {
@ -192,11 +149,14 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
ret = u.validate_relation_data(unit, relation, expected)
if ret:
message = u.relation_error('openstack-dashboard identity-service', ret)
message = u.relation_error('openstack-dashboard identity-service',
ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_keystone_identity_service_relation(self):
"""Verify the keystone to openstack-dashboard identity-service relation data."""
def test_202_keystone_identity_service_relation(self):
"""Verify the keystone to openstack-dashboard identity-service
relation data."""
u.log.debug('Checking keystone:dashboard id relation data...')
unit = self.keystone_sentry
relation = ['identity-service', 'openstack-dashboard:identity-service']
expected = {
@ -214,3 +174,76 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
if ret:
message = u.relation_error('keystone identity-service', ret)
amulet.raise_status(amulet.FAIL, msg=message)
def test_300_local_settings(self):
u.log.debug('Checking dashboard local settings...')
unit = self.openstack_dashboard_sentry
ksentry = self.keystone_sentry
conf = '/etc/openstack-dashboard/local_settings.py'
file_contents = unit.file_contents(conf)
rdata = ksentry.relation('identity-service',
'openstack-dashboard:identity-service')
expected = {
'LOGIN_REDIRECT_URL': """'/horizon'""",
'OPENSTACK_HOST': '"%s"' % (rdata['private-address']),
'OPENSTACK_KEYSTONE_DEFAULT_ROLE': '"Member"'
}
self.crude_py_parse(file_contents, expected)
def test_302_router_settings(self):
u.log.debug('Checking dashboard router settings...')
if self.openstack > "icehouse":
unit = self.openstack_dashboard_sentry
conf = ('/usr/share/openstack-dashboard/openstack_dashboard/'
'enabled/_40_router.py')
file_contents = unit.file_contents(conf)
expected = {
'DISABLED': "True",
}
self.crude_py_parse(file_contents, expected)
def test_400_connection(self):
u.log.debug('Checking dashboard http response...')
unit = self.openstack_dashboard_sentry
dashboard_relation = unit.relation('identity-service',
'keystone:identity-service')
dashboard_ip = dashboard_relation['private-address']
response = urllib2.urlopen('http://%s/horizon' % (dashboard_ip))
html = response.read()
if 'OpenStack Dashboard' not in html:
msg = "Dashboard frontpage check failed"
amulet.raise_status(amulet.FAIL, msg=msg)
def test_900_restart_on_config_change(self):
"""Verify that the specified services are restarted when the
config is changed."""
sentry = self.openstack_dashboard_sentry
juju_service = 'openstack-dashboard'
# Expected default and alternate values
set_default = {'use-syslog': 'False'}
set_alternate = {'use-syslog': 'True'}
# Config file affected by juju set config change
conf_file = '/etc/openstack-dashboard/local_settings.py'
# Services which are expected to restart upon config change
services = ['apache2']
# Make config change, check for service restarts
u.log.debug('Making config change on {}...'.format(juju_service))
self.d.configure(juju_service, set_alternate)
sleep_time = 180
for s in services:
u.log.debug("Checking that service restarted: {}".format(s))
if not u.service_restarted(sentry, s,
conf_file, sleep_time=sleep_time,
pgrep_full=True):
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)