[beisner,r=james-page] auto normalize amulet test definitions and amulet make targets; charm-helper sync.
This commit is contained in:
commit
cf7719934a
|
@ -1 +1 @@
|
|||
€}q(U collectorqUcoverage v3.7.1qUlinesq}qUF/home/jamespage/src/charms/next-resync/ceph-osd/unit_tests/__init__.pyq]qKasu.
|
||||
€}q(U collectorqUcoverage v3.7.1qUlinesq}q(UF/home/jamespage/src/charms/next-resync/ceph-osd/unit_tests/__init__.pyq]qKaUQ/home/jamespage/src/charms/landing-beisner-resync/ceph-osd/unit_tests/__init__.pyq]q Kauu.
|
3
Makefile
3
Makefile
|
@ -14,8 +14,7 @@ test:
|
|||
# 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 --timeout 900 \
|
||||
00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse
|
||||
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
|
||||
|
||||
bin/charm_helpers_sync.py:
|
||||
@mkdir -p bin
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
# Authors:
|
||||
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
||||
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import json
|
||||
import yaml
|
||||
import subprocess
|
||||
import sys
|
||||
import errno
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
import six
|
||||
|
@ -87,7 +89,18 @@ def log(message, level=None):
|
|||
if not isinstance(message, six.string_types):
|
||||
message = repr(message)
|
||||
command += [message]
|
||||
subprocess.call(command)
|
||||
# Missing juju-log should not cause failures in unit tests
|
||||
# Send log output to stderr
|
||||
try:
|
||||
subprocess.call(command)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
if level:
|
||||
message = "{}: {}".format(level, message)
|
||||
message = "juju-log: {}".format(message)
|
||||
print(message, file=sys.stderr)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
class Serializable(UserDict):
|
||||
|
@ -566,3 +579,29 @@ class Hooks(object):
|
|||
def charm_dir():
|
||||
"""Return the root directory of the current charm"""
|
||||
return os.environ.get('CHARM_DIR')
|
||||
|
||||
|
||||
@cached
|
||||
def action_get(key=None):
|
||||
"""Gets the value of an action parameter, or all key/value param pairs"""
|
||||
cmd = ['action-get']
|
||||
if key is not None:
|
||||
cmd.append(key)
|
||||
cmd.append('--format=json')
|
||||
action_data = json.loads(subprocess.check_output(cmd).decode('UTF-8'))
|
||||
return action_data
|
||||
|
||||
|
||||
def action_set(values):
|
||||
"""Sets the values to be returned after the action finishes"""
|
||||
cmd = ['action-set']
|
||||
for k, v in list(values.items()):
|
||||
cmd.append('{}={}'.format(k, v))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def action_fail(message):
|
||||
"""Sets the action status to failed and sets the error message.
|
||||
|
||||
The results set by action_set are preserved."""
|
||||
subprocess.check_call(['action-fail', message])
|
||||
|
|
|
@ -339,12 +339,16 @@ def lsb_release():
|
|||
def pwgen(length=None):
|
||||
"""Generate a random pasword."""
|
||||
if length is None:
|
||||
# A random length is ok to use a weak PRNG
|
||||
length = random.choice(range(35, 45))
|
||||
alphanumeric_chars = [
|
||||
l for l in (string.ascii_letters + string.digits)
|
||||
if l not in 'l0QD1vAEIOUaeiou']
|
||||
# Use a crypto-friendly PRNG (e.g. /dev/urandom) for making the
|
||||
# actual password
|
||||
random_generator = random.SystemRandom()
|
||||
random_chars = [
|
||||
random.choice(alphanumeric_chars) for _ in range(length)]
|
||||
random_generator.choice(alphanumeric_chars) for _ in range(length)]
|
||||
return(''.join(random_chars))
|
||||
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ class MysqlRelation(RelationContext):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.required_keys = ['host', 'user', 'password', 'database']
|
||||
super(HttpRelation).__init__(self, *args, **kwargs)
|
||||
RelationContext.__init__(self, *args, **kwargs)
|
||||
|
||||
|
||||
class HttpRelation(RelationContext):
|
||||
|
@ -154,7 +154,7 @@ class HttpRelation(RelationContext):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.required_keys = ['host', 'port']
|
||||
super(HttpRelation).__init__(self, *args, **kwargs)
|
||||
RelationContext.__init__(self, *args, **kwargs)
|
||||
|
||||
def provide_data(self):
|
||||
return {
|
||||
|
|
|
@ -33,9 +33,9 @@ def bool_from_string(value):
|
|||
|
||||
value = value.strip().lower()
|
||||
|
||||
if value in ['y', 'yes', 'true', 't']:
|
||||
if value in ['y', 'yes', 'true', 't', 'on']:
|
||||
return True
|
||||
elif value in ['n', 'no', 'false', 'f']:
|
||||
elif value in ['n', 'no', 'false', 'f', 'off']:
|
||||
return False
|
||||
|
||||
msg = "Unable to interpret string value '%s' as boolean" % (value)
|
||||
|
|
|
@ -443,7 +443,7 @@ class HookData(object):
|
|||
data = hookenv.execution_environment()
|
||||
self.conf = conf_delta = self.kv.delta(data['conf'], 'config')
|
||||
self.rels = rels_delta = self.kv.delta(data['rels'], 'rels')
|
||||
self.kv.set('env', data['env'])
|
||||
self.kv.set('env', dict(data['env']))
|
||||
self.kv.set('unit', data['unit'])
|
||||
self.kv.set('relid', data.get('relid'))
|
||||
return conf_delta, rels_delta
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic ceph-osd deployment on trusty-juno."""
|
||||
|
||||
from basic_deployment import CephOsdBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = CephOsdBasicDeployment(series='trusty',
|
||||
openstack='cloud:trusty-juno',
|
||||
source='cloud:trusty-updates/juno')
|
||||
deployment.run_tests()
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic ceph-osd deployment on trusty-kilo."""
|
||||
|
||||
from basic_deployment import CephOsdBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = CephOsdBasicDeployment(series='trusty',
|
||||
openstack='cloud:trusty-kilo',
|
||||
source='cloud:trusty-updates/kilo')
|
||||
deployment.run_tests()
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic ceph-osd deployment on utopic-juno."""
|
||||
|
||||
from basic_deployment import CephOsdBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = CephOsdBasicDeployment(series='utopic')
|
||||
deployment.run_tests()
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic ceph-osd deployment on vivid-kilo."""
|
||||
|
||||
from basic_deployment import CephOsdBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = CephOsdBasicDeployment(series='vivid')
|
||||
deployment.run_tests()
|
|
@ -11,7 +11,7 @@ from charmhelpers.contrib.openstack.amulet.utils import ( # noqa
|
|||
)
|
||||
|
||||
# Use DEBUG to turn on debug logging
|
||||
u = OpenStackAmuletUtils(ERROR)
|
||||
u = OpenStackAmuletUtils(DEBUG)
|
||||
|
||||
|
||||
class CephOsdBasicDeployment(OpenStackAmuletDeployment):
|
||||
|
|
|
@ -118,6 +118,9 @@ class AmuletUtils(object):
|
|||
longs, or can be a function that evaluate a variable and returns a
|
||||
bool.
|
||||
"""
|
||||
self.log.debug('actual: {}'.format(repr(actual)))
|
||||
self.log.debug('expected: {}'.format(repr(expected)))
|
||||
|
||||
for k, v in six.iteritems(expected):
|
||||
if k in actual:
|
||||
if (isinstance(v, six.string_types) or
|
||||
|
@ -134,7 +137,6 @@ class AmuletUtils(object):
|
|||
def validate_relation_data(self, sentry_unit, relation, expected):
|
||||
"""Validate actual relation data based on expected relation data."""
|
||||
actual = sentry_unit.relation(relation[0], relation[1])
|
||||
self.log.debug('actual: {}'.format(repr(actual)))
|
||||
return self._validate_dict_data(expected, actual)
|
||||
|
||||
def _validate_list_data(self, expected, actual):
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import six
|
||||
from collections import OrderedDict
|
||||
from charmhelpers.contrib.amulet.deployment import (
|
||||
AmuletDeployment
|
||||
)
|
||||
|
@ -43,7 +44,7 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||
Determine if the local branch being tested is derived from its
|
||||
stable or next (dev) branch, and based on this, use the corresonding
|
||||
stable or next branches for the other_services."""
|
||||
base_charms = ['mysql', 'mongodb', 'rabbitmq-server']
|
||||
base_charms = ['mysql', 'mongodb']
|
||||
|
||||
if self.stable:
|
||||
for svc in other_services:
|
||||
|
@ -100,12 +101,37 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||
"""
|
||||
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
|
||||
self.precise_havana, self.precise_icehouse,
|
||||
self.trusty_icehouse) = range(6)
|
||||
self.trusty_icehouse, self.trusty_juno, self.trusty_kilo,
|
||||
self.utopic_juno, self.vivid_kilo) = range(10)
|
||||
releases = {
|
||||
('precise', None): self.precise_essex,
|
||||
('precise', 'cloud:precise-folsom'): self.precise_folsom,
|
||||
('precise', 'cloud:precise-grizzly'): self.precise_grizzly,
|
||||
('precise', 'cloud:precise-havana'): self.precise_havana,
|
||||
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
|
||||
('trusty', None): self.trusty_icehouse}
|
||||
('trusty', None): self.trusty_icehouse,
|
||||
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
||||
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
|
||||
('utopic', None): self.utopic_juno,
|
||||
('vivid', None): self.vivid_kilo}
|
||||
return releases[(self.series, self.openstack)]
|
||||
|
||||
def _get_openstack_release_string(self):
|
||||
"""Get openstack release string.
|
||||
|
||||
Return a string representing the openstack release.
|
||||
"""
|
||||
releases = OrderedDict([
|
||||
('precise', 'essex'),
|
||||
('quantal', 'folsom'),
|
||||
('raring', 'grizzly'),
|
||||
('saucy', 'havana'),
|
||||
('trusty', 'icehouse'),
|
||||
('utopic', 'juno'),
|
||||
('vivid', 'kilo'),
|
||||
])
|
||||
if self.openstack:
|
||||
os_origin = self.openstack.split(':')[1]
|
||||
return os_origin.split('%s-' % self.series)[1].split('/')[0]
|
||||
else:
|
||||
return releases[self.series]
|
||||
|
|
Loading…
Reference in New Issue