Merge "Enable xenial-pike amulet test"

This commit is contained in:
Zuul 2017-11-20 16:46:47 +00:00 committed by Gerrit Code Review
commit d7795eb5ab
12 changed files with 99 additions and 47 deletions

3
.gitignore vendored
View File

@ -8,3 +8,6 @@ tags
*.pyc
.unit-state.db
.pydevproject
func-results.json
.stestr
joined-string

View File

@ -250,7 +250,14 @@ class OpenStackAmuletDeployment(AmuletDeployment):
self.log.debug('Waiting up to {}s for extended status on services: '
'{}'.format(timeout, services))
service_messages = {service: message for service in services}
# Check for idleness
self.d.sentry.wait()
# Check for error states and bail early
self.d.sentry.wait_for_status(self.d.juju_env, services)
# Check for ready messages
self.d.sentry.wait_for_messages(service_messages, timeout=timeout)
self.log.info('OK')
def _get_openstack_release(self):

View File

@ -43,7 +43,6 @@ import swiftclient
from charmhelpers.contrib.amulet.utils import (
AmuletUtils
)
from charmhelpers.core.decorators import retry_on_exception
from charmhelpers.core.host import CompareHostReleases
DEBUG = logging.DEBUG
@ -311,7 +310,6 @@ class OpenStackAmuletUtils(AmuletUtils):
self.log.debug('Checking if tenant exists ({})...'.format(tenant))
return tenant in [t.name for t in keystone.tenants.list()]
@retry_on_exception(5, base_delay=10)
def keystone_wait_for_propagation(self, sentry_relation_pairs,
api_version):
"""Iterate over list of sentry and relation tuples and verify that
@ -327,7 +325,7 @@ class OpenStackAmuletUtils(AmuletUtils):
rel = sentry.relation('identity-service',
relation_name)
self.log.debug('keystone relation data: {}'.format(rel))
if rel['api_version'] != str(api_version):
if rel.get('api_version') != str(api_version):
raise Exception("api_version not propagated through relation"
" data yet ('{}' != '{}')."
"".format(rel['api_version'], api_version))
@ -349,6 +347,7 @@ class OpenStackAmuletUtils(AmuletUtils):
config = {'preferred-api-version': api_version}
deployment.d.configure('keystone', config)
deployment._auto_wait_for_status()
self.keystone_wait_for_propagation(sentry_relation_pairs, api_version)
def authenticate_cinder_admin(self, keystone_sentry, username,

View File

@ -18,7 +18,7 @@ rbd default features = {{ rbd_features }}
[client]
{% if rbd_client_cache_settings -%}
{% for key, value in rbd_client_cache_settings.iteritems() -%}
{% for key, value in rbd_client_cache_settings.items() -%}
{{ key }} = {{ value }}
{% endfor -%}
{%- endif %}
{%- endif %}

View File

@ -618,7 +618,7 @@ def save_script_rc(script_path="scripts/scriptrc", **env_vars):
juju_rc_path = "%s/%s" % (charm_dir(), script_path)
if not os.path.exists(os.path.dirname(juju_rc_path)):
os.mkdir(os.path.dirname(juju_rc_path))
with open(juju_rc_path, 'wb') as rc_script:
with open(juju_rc_path, 'wt') as rc_script:
rc_script.write(
"#!/bin/bash\n")
[rc_script.write('export %s=%s\n' % (u, p))

View File

@ -61,13 +61,19 @@ def bytes_from_string(value):
if isinstance(value, six.string_types):
value = six.text_type(value)
else:
msg = "Unable to interpret non-string value '%s' as boolean" % (value)
msg = "Unable to interpret non-string value '%s' as bytes" % (value)
raise ValueError(msg)
matches = re.match("([0-9]+)([a-zA-Z]+)", value)
if not matches:
msg = "Unable to interpret string value '%s' as bytes" % (value)
raise ValueError(msg)
return int(matches.group(1)) * (1024 ** BYTE_POWER[matches.group(2)])
if matches:
size = int(matches.group(1)) * (1024 ** BYTE_POWER[matches.group(2)])
else:
# Assume that value passed in is bytes
try:
size = int(value)
except ValueError:
msg = "Unable to interpret string value '%s' as bytes" % (value)
raise ValueError(msg)
return size
class BasicStringComparator(object):

View File

@ -27,8 +27,7 @@ from charmhelpers.contrib.openstack.amulet.deployment import (
# to go undetected. Remove that & fixme.
from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils,
DEBUG, # flake8: noqa
ERROR
DEBUG,
)
# Use DEBUG to turn on debug logging
@ -54,24 +53,20 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
self._deploy()
u.log.info('Waiting on extended status checks...')
# We delay check for services running on neutron-openvswitch unit to
# after verification of sriov configuration. See comment in function
# test_301_neutron_sriov_config()
self.exclude_services = ['neutron-openvswitch']
self._auto_wait_for_status(exclude_services=self.exclude_services)
self.d.sentry.wait()
self._wait_and_check(exclude_services=self.exclude_services)
self._initialize_tests()
def _add_services(self):
"""Add services
Add the services that we're testing, where neutron-openvswitch is local,
and the rest of the service are from lp branches that are
Add the services that we're testing, where neutron-openvswitch is
local, and the rest of the service are from lp branches that are
compatible with the local charm (e.g. stable or next).
"""
# Services and relations which are present merely to satisfy required_interfaces
# and workload status are not inspected. Fix me. Inspect those too.
# Services and relations which are present merely to satisfy
# required_interfaces and workload status are not inspected.
# Fix me. Inspect those too.
this_service = {'name': 'neutron-openvswitch'}
other_services = [
{'name': 'nova-compute'},
@ -117,16 +112,20 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
openstack_origin_git = {
'repositories': [
{'name': 'requirements',
'repository': 'git://github.com/openstack/requirements',
'repository':
'git://github.com/openstack/requirements',
'branch': branch},
{'name': 'neutron-fwaas',
'repository': 'git://github.com/openstack/neutron-fwaas',
'repository':
'git://github.com/openstack/neutron-fwaas',
'branch': branch},
{'name': 'neutron-lbaas',
'repository': 'git://github.com/openstack/neutron-lbaas',
'repository':
'git://github.com/openstack/neutron-lbaas',
'branch': branch},
{'name': 'neutron-vpnaas',
'repository': 'git://github.com/openstack/neutron-vpnaas',
'repository':
'git://github.com/openstack/neutron-vpnaas',
'branch': branch},
{'name': 'neutron',
'repository': 'git://github.com/openstack/neutron',
@ -156,7 +155,8 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
'http_proxy': amulet_http_proxy,
'https_proxy': amulet_http_proxy,
}
neutron_ovs_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
neutron_ovs_config['openstack-origin-git'] = (
yaml.dump(openstack_origin_git))
neutron_ovs_config['enable-sriov'] = True
neutron_ovs_config['sriov-device-mappings'] = 'physnet42:eth42'
@ -181,6 +181,31 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
self.neutron_api_sentry = self.d.sentry['neutron-api'][0]
self.n_ovs_sentry = self.d.sentry['neutron-openvswitch'][0]
def _wait_and_check(self, sleep=5, exclude_services=[]):
"""Extended wait and check helper
The tests for neutron-openvswitch are particularly sensitive to
timing races. This is partially due to the configuration changes being
set against neutron-api and needing to wait for the relation to update
neutron-openvswitch.
This helper will attempt to mitigate these race conditions. It is
purposefully redundant to attempt to handle the races.
This should be called after every self.d.configure() call.
:param sleep: Integer sleep value
:param excluded_services: List of excluded services not to be checked
"""
u.log.debug('Extended wait and check ...')
time.sleep(sleep)
self.d.sentry.wait()
time.sleep(sleep)
self._auto_wait_for_status(exclude_services=exclude_services)
time.sleep(sleep)
self.d.sentry.wait()
u.log.debug('Wait and check completed.')
def test_100_services(self):
"""Verify the expected services are running on the corresponding
service units."""
@ -234,13 +259,12 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
# disable sriov after validation of config file is complete.
u.log.info('Disabling SR-IOV after verifying config file data...')
configs = {
'neutron-openvswitch': { 'enable-sriov': False }
'neutron-openvswitch': {'enable-sriov': False}
}
super(NeutronOVSBasicDeployment, self)._configure_services(configs)
u.log.info('Waiting for config-change to complete...')
self._auto_wait_for_status()
self.d.sentry.wait()
self._wait_and_check()
u.log.debug('OK')
@ -302,7 +326,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
conf = "/etc/neutron/plugins/ml2/ml2_conf.ini"
for value in vpair:
self.d.configure(service, {charm_key: value})
time.sleep(60)
self._wait_and_check()
ret = u.validate_config_data(unit, conf, section,
{config_file_key: value})
msg = "Propagation error, expected %s=%s" % (config_file_key,
@ -341,7 +365,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
self.d.configure('neutron-api', {'neutron-security-groups': 'True'})
self.d.configure('neutron-openvswitch',
{'disable-security-groups': 'True'})
time.sleep(30)
self._wait_and_check()
ret = u.validate_config_data(unit, conf, 'securitygroup',
{'enable_security_group': 'False'})
msg = "Propagation error, expected %s=%s" % ('enable_security_group',
@ -350,7 +374,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
self.d.configure('neutron-openvswitch',
{'disable-security-groups': 'False'})
self.d.configure('neutron-api', {'neutron-security-groups': 'True'})
time.sleep(30)
self._wait_and_check()
ret = u.validate_config_data(unit, conf, 'securitygroup',
{'enable_security_group': 'True'})
@ -376,18 +400,19 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
u.log.debug('Making config change on {}...'.format(juju_service))
mtime = u.get_sentry_time(sentry)
self.d.configure(juju_service, set_alternate)
self._wait_and_check()
sleep_time = 60
sleep_time = 30
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,
sleep_time=sleep_time):
self.d.configure(juju_service, set_default)
self._wait_and_check()
msg = "service {} didn't restart after config change".format(s)
amulet.raise_status(amulet.FAIL, msg=msg)
self.d.configure(juju_service, set_default)
u.log.debug('OK')
def test_400_enable_qos(self):
@ -397,8 +422,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
set_default = {'enable-qos': 'False'}
set_alternate = {'enable-qos': 'True'}
self.d.configure('neutron-api', set_alternate)
time.sleep(60)
self._auto_wait_for_status(exclude_services=self.exclude_services)
self._wait_and_check()
config = u._get_config(
unit,
'/etc/neutron/plugins/ml2/openvswitch_agent.ini')
@ -410,6 +434,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
u.log.debug('Setting QoS back to {}'.format(
set_default['enable-qos']))
self.d.configure('neutron-api', set_default)
self._wait_and_check()
u.log.debug('OK')
def test_910_pause_and_resume(self):

View File

@ -250,7 +250,14 @@ class OpenStackAmuletDeployment(AmuletDeployment):
self.log.debug('Waiting up to {}s for extended status on services: '
'{}'.format(timeout, services))
service_messages = {service: message for service in services}
# Check for idleness
self.d.sentry.wait()
# Check for error states and bail early
self.d.sentry.wait_for_status(self.d.juju_env, services)
# Check for ready messages
self.d.sentry.wait_for_messages(service_messages, timeout=timeout)
self.log.info('OK')
def _get_openstack_release(self):

View File

@ -43,7 +43,6 @@ import swiftclient
from charmhelpers.contrib.amulet.utils import (
AmuletUtils
)
from charmhelpers.core.decorators import retry_on_exception
from charmhelpers.core.host import CompareHostReleases
DEBUG = logging.DEBUG
@ -311,7 +310,6 @@ class OpenStackAmuletUtils(AmuletUtils):
self.log.debug('Checking if tenant exists ({})...'.format(tenant))
return tenant in [t.name for t in keystone.tenants.list()]
@retry_on_exception(5, base_delay=10)
def keystone_wait_for_propagation(self, sentry_relation_pairs,
api_version):
"""Iterate over list of sentry and relation tuples and verify that
@ -327,7 +325,7 @@ class OpenStackAmuletUtils(AmuletUtils):
rel = sentry.relation('identity-service',
relation_name)
self.log.debug('keystone relation data: {}'.format(rel))
if rel['api_version'] != str(api_version):
if rel.get('api_version') != str(api_version):
raise Exception("api_version not propagated through relation"
" data yet ('{}' != '{}')."
"".format(rel['api_version'], api_version))
@ -349,6 +347,7 @@ class OpenStackAmuletUtils(AmuletUtils):
config = {'preferred-api-version': api_version}
deployment.d.configure('keystone', config)
deployment._auto_wait_for_status()
self.keystone_wait_for_propagation(sentry_relation_pairs, api_version)
def authenticate_cinder_admin(self, keystone_sentry, username,

View File

@ -61,13 +61,19 @@ def bytes_from_string(value):
if isinstance(value, six.string_types):
value = six.text_type(value)
else:
msg = "Unable to interpret non-string value '%s' as boolean" % (value)
msg = "Unable to interpret non-string value '%s' as bytes" % (value)
raise ValueError(msg)
matches = re.match("([0-9]+)([a-zA-Z]+)", value)
if not matches:
msg = "Unable to interpret string value '%s' as bytes" % (value)
raise ValueError(msg)
return int(matches.group(1)) * (1024 ** BYTE_POWER[matches.group(2)])
if matches:
size = int(matches.group(1)) * (1024 ** BYTE_POWER[matches.group(2)])
else:
# Assume that value passed in is bytes
try:
size = int(value)
except ValueError:
msg = "Unable to interpret string value '%s' as bytes" % (value)
raise ValueError(msg)
return size
class BasicStringComparator(object):

0
tests/gate-basic-xenial-pike Normal file → Executable file
View File

View File

@ -60,7 +60,7 @@ basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bundletester -vl DEBUG -r json -o func-results.json gate-basic-xenial-mitaka --no-destroy
bundletester -vl DEBUG -r json -o func-results.json gate-basic-xenial-pike --no-destroy
[testenv:func27-dfs]
# Charm Functional Test