Merge lp:~adam-collard/charms/trusty/swift-storage/fix-service-status into lp:~openstack-charmers-archive/charms/trusty/swift-storage/next

Proposed by Adam Collard
Status: Merged
Merged at revision: 73
Proposed branch: lp:~adam-collard/charms/trusty/swift-storage/fix-service-status
Merge into: lp:~openstack-charmers-archive/charms/trusty/swift-storage/next
Diff against target: 543 lines (+178/-93)
11 files modified
charmhelpers/cli/__init__.py (+1/-5)
charmhelpers/cli/commands.py (+4/-4)
charmhelpers/contrib/openstack/amulet/deployment.py (+2/-2)
charmhelpers/contrib/openstack/utils.py (+51/-14)
charmhelpers/contrib/storage/linux/utils.py (+3/-2)
charmhelpers/core/hookenv.py (+1/-20)
charmhelpers/core/host.py (+2/-2)
charmhelpers/fetch/__init__.py (+8/-0)
tests/basic_deployment.py (+20/-21)
tests/charmhelpers/contrib/amulet/utils.py (+84/-21)
tests/charmhelpers/contrib/openstack/amulet/deployment.py (+2/-2)
To merge this branch: bzr merge lp:~adam-collard/charms/trusty/swift-storage/fix-service-status
Reviewer Review Type Date Requested Status
Liam Young (community) Approve
Review via email: mp+268228@code.launchpad.net

Description of the change

Sync charm-helpers and use the (new-ish) validate_services_by_name() utility to properly check that all swift services are starting.

To post a comment you must log in.
75. By Adam Collard

Fix typo

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #8194 swift-storage-next for adam-collard mp268228
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/8194/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #7596 swift-storage-next for adam-collard mp268228
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/7596/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #8195 swift-storage-next for adam-collard mp268228
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/8195/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #7597 swift-storage-next for adam-collard mp268228
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/7597/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #5840 swift-storage-next for adam-collard mp268228
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/12108178/
Build: http://10.245.162.77:8080/job/charm_amulet_test/5840/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #5841 swift-storage-next for adam-collard mp268228
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/5841/

Revision history for this message
Liam Young (gnuoy) wrote :

Approved

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charmhelpers/cli/__init__.py'
--- charmhelpers/cli/__init__.py 2015-07-31 13:11:32 +0000
+++ charmhelpers/cli/__init__.py 2015-08-17 13:36:14 +0000
@@ -152,15 +152,11 @@
152 arguments = self.argument_parser.parse_args()152 arguments = self.argument_parser.parse_args()
153 argspec = inspect.getargspec(arguments.func)153 argspec = inspect.getargspec(arguments.func)
154 vargs = []154 vargs = []
155 kwargs = {}
156 for arg in argspec.args:155 for arg in argspec.args:
157 vargs.append(getattr(arguments, arg))156 vargs.append(getattr(arguments, arg))
158 if argspec.varargs:157 if argspec.varargs:
159 vargs.extend(getattr(arguments, argspec.varargs))158 vargs.extend(getattr(arguments, argspec.varargs))
160 if argspec.keywords:159 output = arguments.func(*vargs)
161 for kwarg in argspec.keywords.items():
162 kwargs[kwarg] = getattr(arguments, kwarg)
163 output = arguments.func(*vargs, **kwargs)
164 if getattr(arguments.func, '_cli_test_command', False):160 if getattr(arguments.func, '_cli_test_command', False):
165 self.exit_code = 0 if output else 1161 self.exit_code = 0 if output else 1
166 output = ''162 output = ''
167163
=== modified file 'charmhelpers/cli/commands.py'
--- charmhelpers/cli/commands.py 2015-07-31 13:11:32 +0000
+++ charmhelpers/cli/commands.py 2015-08-17 13:36:14 +0000
@@ -26,7 +26,7 @@
26"""26"""
27Import the sub-modules which have decorated subcommands to register with chlp.27Import the sub-modules which have decorated subcommands to register with chlp.
28"""28"""
29import host # noqa29from . import host # noqa
30import benchmark # noqa30from . import benchmark # noqa
31import unitdata # noqa31from . import unitdata # noqa
32from charmhelpers.core import hookenv # noqa32from . import hookenv # noqa
3333
=== modified file 'charmhelpers/contrib/openstack/amulet/deployment.py'
--- charmhelpers/contrib/openstack/amulet/deployment.py 2015-07-29 10:49:43 +0000
+++ charmhelpers/contrib/openstack/amulet/deployment.py 2015-08-17 13:36:14 +0000
@@ -44,7 +44,7 @@
44 Determine if the local branch being tested is derived from its44 Determine if the local branch being tested is derived from its
45 stable or next (dev) branch, and based on this, use the corresonding45 stable or next (dev) branch, and based on this, use the corresonding
46 stable or next branches for the other_services."""46 stable or next branches for the other_services."""
47 base_charms = ['mysql', 'mongodb']47 base_charms = ['mysql', 'mongodb', 'nrpe']
4848
49 if self.series in ['precise', 'trusty']:49 if self.series in ['precise', 'trusty']:
50 base_series = self.series50 base_series = self.series
@@ -81,7 +81,7 @@
81 'ceph-osd', 'ceph-radosgw']81 'ceph-osd', 'ceph-radosgw']
82 # Most OpenStack subordinate charms do not expose an origin option82 # Most OpenStack subordinate charms do not expose an origin option
83 # as that is controlled by the principle.83 # as that is controlled by the principle.
84 ignore = ['cinder-ceph', 'hacluster', 'neutron-openvswitch']84 ignore = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe']
8585
86 if self.openstack:86 if self.openstack:
87 for svc in services:87 for svc in services:
8888
=== modified file 'charmhelpers/contrib/openstack/utils.py'
--- charmhelpers/contrib/openstack/utils.py 2015-07-29 10:49:43 +0000
+++ charmhelpers/contrib/openstack/utils.py 2015-08-17 13:36:14 +0000
@@ -24,6 +24,7 @@
24import json24import json
25import os25import os
26import sys26import sys
27import re
2728
28import six29import six
29import yaml30import yaml
@@ -69,7 +70,6 @@
69DISTRO_PROPOSED = ('deb http://archive.ubuntu.com/ubuntu/ %s-proposed '70DISTRO_PROPOSED = ('deb http://archive.ubuntu.com/ubuntu/ %s-proposed '
70 'restricted main multiverse universe')71 'restricted main multiverse universe')
7172
72
73UBUNTU_OPENSTACK_RELEASE = OrderedDict([73UBUNTU_OPENSTACK_RELEASE = OrderedDict([
74 ('oneiric', 'diablo'),74 ('oneiric', 'diablo'),
75 ('precise', 'essex'),75 ('precise', 'essex'),
@@ -118,6 +118,34 @@
118 ('2.3.0', 'liberty'),118 ('2.3.0', 'liberty'),
119])119])
120120
121# >= Liberty version->codename mapping
122PACKAGE_CODENAMES = {
123 'nova-common': OrderedDict([
124 ('12.0.0', 'liberty'),
125 ]),
126 'neutron-common': OrderedDict([
127 ('7.0.0', 'liberty'),
128 ]),
129 'cinder-common': OrderedDict([
130 ('7.0.0', 'liberty'),
131 ]),
132 'keystone': OrderedDict([
133 ('8.0.0', 'liberty'),
134 ]),
135 'horizon-common': OrderedDict([
136 ('8.0.0', 'liberty'),
137 ]),
138 'ceilometer-common': OrderedDict([
139 ('5.0.0', 'liberty'),
140 ]),
141 'heat-common': OrderedDict([
142 ('5.0.0', 'liberty'),
143 ]),
144 'glance-common': OrderedDict([
145 ('11.0.0', 'liberty'),
146 ]),
147}
148
121DEFAULT_LOOPBACK_SIZE = '5G'149DEFAULT_LOOPBACK_SIZE = '5G'
122150
123151
@@ -201,20 +229,29 @@
201 error_out(e)229 error_out(e)
202230
203 vers = apt.upstream_version(pkg.current_ver.ver_str)231 vers = apt.upstream_version(pkg.current_ver.ver_str)
232 match = re.match('^(\d)\.(\d)\.(\d)', vers)
233 if match:
234 vers = match.group(0)
204235
205 try:236 # >= Liberty independent project versions
206 if 'swift' in pkg.name:237 if (package in PACKAGE_CODENAMES and
207 swift_vers = vers[:5]238 vers in PACKAGE_CODENAMES[package]):
208 if swift_vers not in SWIFT_CODENAMES:239 return PACKAGE_CODENAMES[package][vers]
209 # Deal with 1.10.0 upward240 else:
210 swift_vers = vers[:6]241 # < Liberty co-ordinated project versions
211 return SWIFT_CODENAMES[swift_vers]242 try:
212 else:243 if 'swift' in pkg.name:
213 vers = vers[:6]244 swift_vers = vers[:5]
214 return OPENSTACK_CODENAMES[vers]245 if swift_vers not in SWIFT_CODENAMES:
215 except KeyError:246 # Deal with 1.10.0 upward
216 e = 'Could not determine OpenStack codename for version %s' % vers247 swift_vers = vers[:6]
217 error_out(e)248 return SWIFT_CODENAMES[swift_vers]
249 else:
250 vers = vers[:6]
251 return OPENSTACK_CODENAMES[vers]
252 except KeyError:
253 e = 'Could not determine OpenStack codename for version %s' % vers
254 error_out(e)
218255
219256
220def get_os_version_package(pkg, fatal=True):257def get_os_version_package(pkg, fatal=True):
221258
=== modified file 'charmhelpers/contrib/storage/linux/utils.py'
--- charmhelpers/contrib/storage/linux/utils.py 2015-07-29 10:49:43 +0000
+++ charmhelpers/contrib/storage/linux/utils.py 2015-08-17 13:36:14 +0000
@@ -43,9 +43,10 @@
4343
44 :param block_device: str: Full path of block device to clean.44 :param block_device: str: Full path of block device to clean.
45 '''45 '''
46 # https://github.com/ceph/ceph/commit/fdd7f8d83afa25c4e09aaedd90ab93f3b64a677b
46 # sometimes sgdisk exits non-zero; this is OK, dd will clean up47 # sometimes sgdisk exits non-zero; this is OK, dd will clean up
47 call(['sgdisk', '--zap-all', '--mbrtogpt',48 call(['sgdisk', '--zap-all', '--', block_device])
48 '--clear', block_device])49 call(['sgdisk', '--clear', '--mbrtogpt', '--', block_device])
49 dev_end = check_output(['blockdev', '--getsz',50 dev_end = check_output(['blockdev', '--getsz',
50 block_device]).decode('UTF-8')51 block_device]).decode('UTF-8')
51 gpt_end = int(dev_end.split()[0]) - 10052 gpt_end = int(dev_end.split()[0]) - 100
5253
=== modified file 'charmhelpers/core/hookenv.py'
--- charmhelpers/core/hookenv.py 2015-08-03 14:00:44 +0000
+++ charmhelpers/core/hookenv.py 2015-08-17 13:36:14 +0000
@@ -34,23 +34,6 @@
34import tempfile34import tempfile
35from subprocess import CalledProcessError35from subprocess import CalledProcessError
3636
37try:
38 from charmhelpers.cli import cmdline
39except ImportError as e:
40 # due to the anti-pattern of partially synching charmhelpers directly
41 # into charms, it's possible that charmhelpers.cli is not available;
42 # if that's the case, they don't really care about using the cli anyway,
43 # so mock it out
44 if str(e) == 'No module named cli':
45 class cmdline(object):
46 @classmethod
47 def subcommand(cls, *args, **kwargs):
48 def _wrap(func):
49 return func
50 return _wrap
51 else:
52 raise
53
54import six37import six
55if not six.PY3:38if not six.PY3:
56 from UserDict import UserDict39 from UserDict import UserDict
@@ -91,6 +74,7 @@
91 res = func(*args, **kwargs)74 res = func(*args, **kwargs)
92 cache[key] = res75 cache[key] = res
93 return res76 return res
77 wrapper._wrapped = func
94 return wrapper78 return wrapper
9579
9680
@@ -190,7 +174,6 @@
190 return os.environ.get('JUJU_RELATION', None)174 return os.environ.get('JUJU_RELATION', None)
191175
192176
193@cmdline.subcommand()
194@cached177@cached
195def relation_id(relation_name=None, service_or_unit=None):178def relation_id(relation_name=None, service_or_unit=None):
196 """The relation ID for the current or a specified relation"""179 """The relation ID for the current or a specified relation"""
@@ -216,13 +199,11 @@
216 return os.environ.get('JUJU_REMOTE_UNIT', None)199 return os.environ.get('JUJU_REMOTE_UNIT', None)
217200
218201
219@cmdline.subcommand()
220def service_name():202def service_name():
221 """The name service group this unit belongs to"""203 """The name service group this unit belongs to"""
222 return local_unit().split('/')[0]204 return local_unit().split('/')[0]
223205
224206
225@cmdline.subcommand()
226@cached207@cached
227def remote_service_name(relid=None):208def remote_service_name(relid=None):
228 """The remote service name for a given relation-id (or the current relation)"""209 """The remote service name for a given relation-id (or the current relation)"""
229210
=== modified file 'charmhelpers/core/host.py'
--- charmhelpers/core/host.py 2015-07-29 10:49:43 +0000
+++ charmhelpers/core/host.py 2015-08-17 13:36:14 +0000
@@ -72,7 +72,7 @@
72 stopped = service_stop(service_name)72 stopped = service_stop(service_name)
73 # XXX: Support systemd too73 # XXX: Support systemd too
74 override_path = os.path.join(74 override_path = os.path.join(
75 init_dir, '{}.conf.override'.format(service_name))75 init_dir, '{}.override'.format(service_name))
76 with open(override_path, 'w') as fh:76 with open(override_path, 'w') as fh:
77 fh.write("manual\n")77 fh.write("manual\n")
78 return stopped78 return stopped
@@ -86,7 +86,7 @@
86 if init_dir is None:86 if init_dir is None:
87 init_dir = "/etc/init"87 init_dir = "/etc/init"
88 override_path = os.path.join(88 override_path = os.path.join(
89 init_dir, '{}.conf.override'.format(service_name))89 init_dir, '{}.override'.format(service_name))
90 if os.path.exists(override_path):90 if os.path.exists(override_path):
91 os.unlink(override_path)91 os.unlink(override_path)
92 started = service_start(service_name)92 started = service_start(service_name)
9393
=== modified file 'charmhelpers/fetch/__init__.py'
--- charmhelpers/fetch/__init__.py 2015-07-29 10:49:43 +0000
+++ charmhelpers/fetch/__init__.py 2015-08-17 13:36:14 +0000
@@ -90,6 +90,14 @@
90 'kilo/proposed': 'trusty-proposed/kilo',90 'kilo/proposed': 'trusty-proposed/kilo',
91 'trusty-kilo/proposed': 'trusty-proposed/kilo',91 'trusty-kilo/proposed': 'trusty-proposed/kilo',
92 'trusty-proposed/kilo': 'trusty-proposed/kilo',92 'trusty-proposed/kilo': 'trusty-proposed/kilo',
93 # Liberty
94 'liberty': 'trusty-updates/liberty',
95 'trusty-liberty': 'trusty-updates/liberty',
96 'trusty-liberty/updates': 'trusty-updates/liberty',
97 'trusty-updates/liberty': 'trusty-updates/liberty',
98 'liberty/proposed': 'trusty-proposed/liberty',
99 'trusty-liberty/proposed': 'trusty-proposed/liberty',
100 'trusty-proposed/liberty': 'trusty-proposed/liberty',
93}101}
94102
95# The order of this list is very important. Handlers should be listed in from103# The order of this list is very important. Handlers should be listed in from
96104
=== modified file 'tests/basic_deployment.py'
--- tests/basic_deployment.py 2015-04-16 21:31:35 +0000
+++ tests/basic_deployment.py 2015-08-17 13:36:14 +0000
@@ -1,5 +1,3 @@
1#!/usr/bin/python
2
3import amulet1import amulet
4import swiftclient2import swiftclient
53
@@ -122,29 +120,30 @@
122 def test_services(self):120 def test_services(self):
123 """Verify the expected services are running on the corresponding121 """Verify the expected services are running on the corresponding
124 service units."""122 service units."""
125 swift_storage_services = ['status swift-account',123 swift_storage_services = ['swift-account',
126 'status swift-account-auditor',124 'swift-account-auditor',
127 'status swift-account-reaper',125 'swift-account-reaper',
128 'status swift-account-replicator',126 'swift-account-replicator',
129 'status swift-container',127 'swift-container',
130 'status swift-container-auditor',128 'swift-container-auditor',
131 'status swift-container-replicator',129 'swift-container-replicator',
132 'status swift-container-updater',130 'swift-container-updater',
133 'status swift-object',131 'swift-object',
134 'status swift-object-auditor',132 'swift-object-auditor',
135 'status swift-object-replicator',133 'swift-object-replicator',
136 'status swift-object-updater']134 'swift-object-updater']
137 if self._get_openstack_release() >= self.precise_icehouse:135 if self._get_openstack_release() >= self.precise_icehouse:
138 swift_storage_services.append('status swift-container-sync')136 swift_storage_services.append('swift-container-sync')
139 commands = {137 service_names = {
140 self.mysql_sentry: ['status mysql'],138 self.mysql_sentry: ['mysql'],
141 self.keystone_sentry: ['status keystone'],139 self.keystone_sentry: ['keystone'],
142 self.glance_sentry: ['status glance-registry', 'status glance-api'],140 self.glance_sentry: [
143 self.swift_proxy_sentry: ['status swift-proxy'],141 'glance-registry', 'glance-api'],
142 self.swift_proxy_sentry: ['swift-proxy'],
144 self.swift_storage_sentry: swift_storage_services143 self.swift_storage_sentry: swift_storage_services
145 }144 }
146145
147 ret = u.validate_services(commands)146 ret = u.validate_services_by_name(service_names)
148 if ret:147 if ret:
149 amulet.raise_status(amulet.FAIL, msg=ret)148 amulet.raise_status(amulet.FAIL, msg=ret)
150149
151150
=== modified file 'tests/charmhelpers/contrib/amulet/utils.py'
--- tests/charmhelpers/contrib/amulet/utils.py 2015-07-29 10:49:43 +0000
+++ tests/charmhelpers/contrib/amulet/utils.py 2015-08-17 13:36:14 +0000
@@ -14,17 +14,23 @@
14# You should have received a copy of the GNU Lesser General Public License14# You should have received a copy of the GNU Lesser General Public License
15# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.15# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
1616
17import amulet
18import ConfigParser
19import distro_info
20import io17import io
18import json
21import logging19import logging
22import os20import os
23import re21import re
24import six22import subprocess
25import sys23import sys
26import time24import time
27import urlparse25
26import amulet
27import distro_info
28import six
29from six.moves import configparser
30if six.PY3:
31 from urllib import parse as urlparse
32else:
33 import urlparse
2834
2935
30class AmuletUtils(object):36class AmuletUtils(object):
@@ -142,19 +148,23 @@
142148
143 for service_name in services_list:149 for service_name in services_list:
144 if (self.ubuntu_releases.index(release) >= systemd_switch or150 if (self.ubuntu_releases.index(release) >= systemd_switch or
145 service_name == "rabbitmq-server"):151 service_name in ['rabbitmq-server', 'apache2']):
146 # init is systemd152 # init is systemd (or regular sysv)
147 cmd = 'sudo service {} status'.format(service_name)153 cmd = 'sudo service {} status'.format(service_name)
154 output, code = sentry_unit.run(cmd)
155 service_running = code == 0
148 elif self.ubuntu_releases.index(release) < systemd_switch:156 elif self.ubuntu_releases.index(release) < systemd_switch:
149 # init is upstart157 # init is upstart
150 cmd = 'sudo status {}'.format(service_name)158 cmd = 'sudo status {}'.format(service_name)
159 output, code = sentry_unit.run(cmd)
160 service_running = code == 0 and "start/running" in output
151161
152 output, code = sentry_unit.run(cmd)
153 self.log.debug('{} `{}` returned '162 self.log.debug('{} `{}` returned '
154 '{}'.format(sentry_unit.info['unit_name'],163 '{}'.format(sentry_unit.info['unit_name'],
155 cmd, code))164 cmd, code))
156 if code != 0:165 if not service_running:
157 return "command `{}` returned {}".format(cmd, str(code))166 return u"command `{}` returned {} {}".format(
167 cmd, output, str(code))
158 return None168 return None
159169
160 def _get_config(self, unit, filename):170 def _get_config(self, unit, filename):
@@ -164,7 +174,7 @@
164 # NOTE(beisner): by default, ConfigParser does not handle options174 # NOTE(beisner): by default, ConfigParser does not handle options
165 # with no value, such as the flags used in the mysql my.cnf file.175 # with no value, such as the flags used in the mysql my.cnf file.
166 # https://bugs.python.org/issue7005176 # https://bugs.python.org/issue7005
167 config = ConfigParser.ConfigParser(allow_no_value=True)177 config = configparser.ConfigParser(allow_no_value=True)
168 config.readfp(io.StringIO(file_contents))178 config.readfp(io.StringIO(file_contents))
169 return config179 return config
170180
@@ -450,15 +460,20 @@
450 cmd, code, output))460 cmd, code, output))
451 return None461 return None
452462
453 def get_process_id_list(self, sentry_unit, process_name):463 def get_process_id_list(self, sentry_unit, process_name,
464 expect_success=True):
454 """Get a list of process ID(s) from a single sentry juju unit465 """Get a list of process ID(s) from a single sentry juju unit
455 for a single process name.466 for a single process name.
456467
457 :param sentry_unit: Pointer to amulet sentry instance (juju unit)468 :param sentry_unit: Amulet sentry instance (juju unit)
458 :param process_name: Process name469 :param process_name: Process name
470 :param expect_success: If False, expect the PID to be missing,
471 raise if it is present.
459 :returns: List of process IDs472 :returns: List of process IDs
460 """473 """
461 cmd = 'pidof {}'.format(process_name)474 cmd = 'pidof -x {}'.format(process_name)
475 if not expect_success:
476 cmd += " || exit 0 && exit 1"
462 output, code = sentry_unit.run(cmd)477 output, code = sentry_unit.run(cmd)
463 if code != 0:478 if code != 0:
464 msg = ('{} `{}` returned {} '479 msg = ('{} `{}` returned {} '
@@ -467,14 +482,23 @@
467 amulet.raise_status(amulet.FAIL, msg=msg)482 amulet.raise_status(amulet.FAIL, msg=msg)
468 return str(output).split()483 return str(output).split()
469484
470 def get_unit_process_ids(self, unit_processes):485 def get_unit_process_ids(self, unit_processes, expect_success=True):
471 """Construct a dict containing unit sentries, process names, and486 """Construct a dict containing unit sentries, process names, and
472 process IDs."""487 process IDs.
488
489 :param unit_processes: A dictionary of Amulet sentry instance
490 to list of process names.
491 :param expect_success: if False expect the processes to not be
492 running, raise if they are.
493 :returns: Dictionary of Amulet sentry instance to dictionary
494 of process names to PIDs.
495 """
473 pid_dict = {}496 pid_dict = {}
474 for sentry_unit, process_list in unit_processes.iteritems():497 for sentry_unit, process_list in six.iteritems(unit_processes):
475 pid_dict[sentry_unit] = {}498 pid_dict[sentry_unit] = {}
476 for process in process_list:499 for process in process_list:
477 pids = self.get_process_id_list(sentry_unit, process)500 pids = self.get_process_id_list(
501 sentry_unit, process, expect_success=expect_success)
478 pid_dict[sentry_unit].update({process: pids})502 pid_dict[sentry_unit].update({process: pids})
479 return pid_dict503 return pid_dict
480504
@@ -488,7 +512,7 @@
488 return ('Unit count mismatch. expected, actual: {}, '512 return ('Unit count mismatch. expected, actual: {}, '
489 '{} '.format(len(expected), len(actual)))513 '{} '.format(len(expected), len(actual)))
490514
491 for (e_sentry, e_proc_names) in expected.iteritems():515 for (e_sentry, e_proc_names) in six.iteritems(expected):
492 e_sentry_name = e_sentry.info['unit_name']516 e_sentry_name = e_sentry.info['unit_name']
493 if e_sentry in actual.keys():517 if e_sentry in actual.keys():
494 a_proc_names = actual[e_sentry]518 a_proc_names = actual[e_sentry]
@@ -507,11 +531,23 @@
507 '{}'.format(e_proc_name, a_proc_name))531 '{}'.format(e_proc_name, a_proc_name))
508532
509 a_pids_length = len(a_pids)533 a_pids_length = len(a_pids)
510 if e_pids_length != a_pids_length:534 fail_msg = ('PID count mismatch. {} ({}) expected, actual: '
511 return ('PID count mismatch. {} ({}) expected, actual: '
512 '{}, {} ({})'.format(e_sentry_name, e_proc_name,535 '{}, {} ({})'.format(e_sentry_name, e_proc_name,
513 e_pids_length, a_pids_length,536 e_pids_length, a_pids_length,
514 a_pids))537 a_pids))
538
539 # If expected is not bool, ensure PID quantities match
540 if not isinstance(e_pids_length, bool) and \
541 a_pids_length != e_pids_length:
542 return fail_msg
543 # If expected is bool True, ensure 1 or more PIDs exist
544 elif isinstance(e_pids_length, bool) and \
545 e_pids_length is True and a_pids_length < 1:
546 return fail_msg
547 # If expected is bool False, ensure 0 PIDs exist
548 elif isinstance(e_pids_length, bool) and \
549 e_pids_length is False and a_pids_length != 0:
550 return fail_msg
515 else:551 else:
516 self.log.debug('PID check OK: {} {} {}: '552 self.log.debug('PID check OK: {} {} {}: '
517 '{}'.format(e_sentry_name, e_proc_name,553 '{}'.format(e_sentry_name, e_proc_name,
@@ -531,3 +567,30 @@
531 return 'Dicts within list are not identical'567 return 'Dicts within list are not identical'
532568
533 return None569 return None
570
571 def run_action(self, unit_sentry, action,
572 _check_output=subprocess.check_output):
573 """Run the named action on a given unit sentry.
574
575 _check_output parameter is used for dependency injection.
576
577 @return action_id.
578 """
579 unit_id = unit_sentry.info["unit_name"]
580 command = ["juju", "action", "do", "--format=json", unit_id, action]
581 self.log.info("Running command: %s\n" % " ".join(command))
582 output = _check_output(command, universal_newlines=True)
583 data = json.loads(output)
584 action_id = data[u'Action queued with id']
585 return action_id
586
587 def wait_on_action(self, action_id, _check_output=subprocess.check_output):
588 """Wait for a given action, returning if it completed or not.
589
590 _check_output parameter is used for dependency injection.
591 """
592 command = ["juju", "action", "fetch", "--format=json", "--wait=0",
593 action_id]
594 output = _check_output(command, universal_newlines=True)
595 data = json.loads(output)
596 return data.get(u"status") == "completed"
534597
=== modified file 'tests/charmhelpers/contrib/openstack/amulet/deployment.py'
--- tests/charmhelpers/contrib/openstack/amulet/deployment.py 2015-07-29 10:49:43 +0000
+++ tests/charmhelpers/contrib/openstack/amulet/deployment.py 2015-08-17 13:36:14 +0000
@@ -44,7 +44,7 @@
44 Determine if the local branch being tested is derived from its44 Determine if the local branch being tested is derived from its
45 stable or next (dev) branch, and based on this, use the corresonding45 stable or next (dev) branch, and based on this, use the corresonding
46 stable or next branches for the other_services."""46 stable or next branches for the other_services."""
47 base_charms = ['mysql', 'mongodb']47 base_charms = ['mysql', 'mongodb', 'nrpe']
4848
49 if self.series in ['precise', 'trusty']:49 if self.series in ['precise', 'trusty']:
50 base_series = self.series50 base_series = self.series
@@ -81,7 +81,7 @@
81 'ceph-osd', 'ceph-radosgw']81 'ceph-osd', 'ceph-radosgw']
82 # Most OpenStack subordinate charms do not expose an origin option82 # Most OpenStack subordinate charms do not expose an origin option
83 # as that is controlled by the principle.83 # as that is controlled by the principle.
84 ignore = ['cinder-ceph', 'hacluster', 'neutron-openvswitch']84 ignore = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe']
8585
86 if self.openstack:86 if self.openstack:
87 for svc in services:87 for svc in services:

Subscribers

People subscribed via source and target branches