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
compatible with the local charm (e.g. stable or next).
"""
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',
'keystone:shared-db': 'mysql:shared-db',
'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."""
@ -72,7 +74,7 @@ class OpenstackDashboardBasicDeployment(OpenStackAmuletDeployment):
openstack_origin_git = {
'repositories': [
{'name': 'requirements',
'repository': reqs_repo,
'repository': reqs_repo,
'branch': branch},
{'name': 'horizon',
'repository': horizon_repo,
@ -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,99 +93,53 @@ 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'):
if '=' in line:
args = line.split('=')
if len(args) <= 1:
continue
key = args[0].strip()
value = args[1].strip()
if key in expected.keys():
if expected[key] != value:
msg="Mismatch %s != %s" % (expected[key], value)
amulet.raise_status(amulet.FAIL, msg=msg)
args = line.split('=')
if len(args) <= 1:
continue
key = args[0].strip()
value = args[1].strip()
if key in expected.keys():
if expected[key] != value:
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)