Merge lp:~1chb1n/charms/trusty/openstack-dashboard/next-amulet-fixup-1507 into lp:~openstack-charmers-archive/charms/trusty/openstack-dashboard/next

Proposed by Ryan Beisner
Status: Merged
Merged at revision: 84
Proposed branch: lp:~1chb1n/charms/trusty/openstack-dashboard/next-amulet-fixup-1507
Merge into: lp:~openstack-charmers-archive/charms/trusty/openstack-dashboard/next
Diff against target: 699 lines (+287/-180)
7 files modified
Makefile (+10/-10)
metadata.yaml (+3/-1)
tests/00-setup (+7/-3)
tests/README (+10/-0)
tests/basic_deployment.py (+136/-113)
tests/charmhelpers/contrib/amulet/utils.py (+101/-53)
tests/tests.yaml (+20/-0)
To merge this branch: bzr merge lp:~1chb1n/charms/trusty/openstack-dashboard/next-amulet-fixup-1507
Reviewer Review Type Date Requested Status
Billy Olsen Pending
OpenStack Charmers Pending
Review via email: mp+268930@code.launchpad.net

This proposal supersedes a proposal from 2015-08-01.

Description of the change

Update tests for T-K, V-K, prep for T-L and W-L. Clean up old lint. Resolve bug 1474030 race in svc restart checks.

This merge proposal is dependent on the corresponding charm-helpers changes landing:
https://code.launchpad.net/~1chb1n/charm-helpers/amulet-svc-restart-race

To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_lint_check #7402 openstack-dashboard-next for 1chb1n mp266642
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_unit_test #6868 openstack-dashboard-next for 1chb1n mp266642
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5552 openstack-dashboard-next for 1chb1n mp266642
    AMULET FAIL: amulet-test failed

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

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5554 openstack-dashboard-next for 1chb1n mp266642
    AMULET FAIL: amulet-test failed

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

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_lint_check #7428 openstack-dashboard-next for 1chb1n mp266642
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_unit_test #6892 openstack-dashboard-next for 1chb1n mp266642
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5557 openstack-dashboard-next for 1chb1n mp266642
    AMULET FAIL: amulet-test failed

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

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

Revision history for this message
Ryan Beisner (1chb1n) wrote : Posted in a previous version of this proposal

^ NOTE: All non-git amulet tests are passing.

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_lint_check #8490 openstack-dashboard-next for 1chb1n mp266642
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_unit_test #7881 openstack-dashboard-next for 1chb1n mp266642
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5951 openstack-dashboard-next for 1chb1n mp266642
    AMULET OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_lint_check #8542 openstack-dashboard-next for 1chb1n mp266642
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_unit_test #7931 openstack-dashboard-next for 1chb1n mp266642
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5954 openstack-dashboard-next for 1chb1n mp266642
    AMULET OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_lint_check #8545 openstack-dashboard-next for 1chb1n mp266642
    LINT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_unit_test #7933 openstack-dashboard-next for 1chb1n mp266642
    UNIT OK: passed

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5960 openstack-dashboard-next for 1chb1n mp266642
    AMULET FAIL: amulet-test failed

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

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

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal

charm_amulet_test #5959 openstack-dashboard-next for 1chb1n mp266642
    AMULET OK: passed

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

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

charm_lint_check #8651 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #7988 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

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

charm_amulet_test #6016 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

87. By Ryan Beisner

update test & resync tests/charmhelpers re: bug 1474030 in service restarted check

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

charm_lint_check #8705 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #8040 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

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

charm_amulet_test #6031 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

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

charm_lint_check #8830 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #8158 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

88. By Ryan Beisner

update test & resync tests/charmhelpers re: bug 1474030 in service restarted check

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

charm_lint_check #8832 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #8160 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

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

charm_amulet_test #6064 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

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

charm_amulet_test #6066 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

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

charm_amulet_test #6072 openstack-dashboard-next for 1chb1n mp268930
    AMULET FAIL: amulet-test failed

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

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

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

charm_amulet_test #6073 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

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

charm_lint_check #8931 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #8255 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

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

charm_amulet_test #6076 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

89. By Ryan Beisner

resync tests/charmhelpers

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

charm_lint_check #9225 openstack-dashboard-next for 1chb1n mp268930
    LINT OK: passed

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

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

charm_unit_test #8526 openstack-dashboard-next for 1chb1n mp268930
    UNIT OK: passed

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

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

charm_amulet_test #6188 openstack-dashboard-next for 1chb1n mp268930
    AMULET OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2015-04-16 21:32:06 +0000
3+++ Makefile 2015-09-02 02:02:17 +0000
4@@ -2,12 +2,19 @@
5 PYTHON := /usr/bin/env python
6
7 lint:
8- @flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests
9+ @flake8 --exclude hooks/charmhelpers,tests/charmhelpers \
10+ actions hooks unit_tests tests
11 @charm proof
12
13-unit_test:
14+test:
15+ @# Bundletester expects unit tests here.
16 @echo Starting tests...
17- @$(PYTHON) /usr/bin/nosetests --nologcapture unit_tests
18+ @$(PYTHON) /usr/bin/nosetests --nologcapture --with-coverage unit_tests
19+
20+functional_test:
21+ @echo Starting Amulet tests...
22+ # https://bugs.launchpad.net/amulet/+bug/1320357
23+ @juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
24
25 bin/charm_helpers_sync.py:
26 @mkdir -p bin
27@@ -18,13 +25,6 @@
28 @$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
29 @$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-tests.yaml
30
31-test:
32- @echo Starting Amulet tests...
33- # coreycb note: The -v should only be temporary until Amulet sends
34- # raise_status() messages to stderr:
35- # https://bugs.launchpad.net/amulet/+bug/1320357
36- @juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
37-
38 publish: lint test
39 bzr push lp:charms/openstack-dashboard
40 bzr push lp:charms/trusty/openstack-dashboard
41
42=== modified file 'metadata.yaml'
43--- metadata.yaml 2014-10-30 03:30:36 +0000
44+++ metadata.yaml 2015-09-02 02:02:17 +0000
45@@ -4,7 +4,9 @@
46 description: |
47 The OpenStack Dashboard provides a full feature web interface for interacting
48 with instances, images, volumes and networks within an OpenStack deployment.
49-categories: ["misc"]
50+tags:
51+ - openstack
52+ - misc
53 provides:
54 nrpe-external-master:
55 interface: nrpe-external-master
56
57=== modified file 'tests/00-setup'
58--- tests/00-setup 2015-07-10 13:34:04 +0000
59+++ tests/00-setup 2015-09-02 02:02:17 +0000
60@@ -4,9 +4,13 @@
61
62 sudo add-apt-repository --yes ppa:juju/stable
63 sudo apt-get update --yes
64-sudo apt-get install --yes python-amulet \
65+sudo apt-get install --yes amulet \
66+ python-cinderclient \
67 python-distro-info \
68+ python-glanceclient \
69+ python-heatclient \
70+ python-keystoneclient \
71 python-neutronclient \
72- python-keystoneclient \
73 python-novaclient \
74- python-glanceclient
75+ python-pika \
76+ python-swiftclient
77
78=== modified file 'tests/019-basic-vivid-kilo' (properties changed: -x to +x)
79=== modified file 'tests/README'
80--- tests/README 2015-02-12 13:03:59 +0000
81+++ tests/README 2015-09-02 02:02:17 +0000
82@@ -1,6 +1,16 @@
83 This directory provides Amulet tests that focus on verification of
84 openstack-dashboard deployments.
85
86+test_* methods are called in lexical sort order, although each individual test
87+should be idempotent, and expected to pass regardless of run order.
88+
89+Test name convention to ensure desired test order:
90+ 1xx service and endpoint checks
91+ 2xx relation checks
92+ 3xx config checks
93+ 4xx functional checks
94+ 9xx restarts and other final checks
95+
96 In order to run tests, you'll need charm-tools installed (in addition to
97 juju, of course):
98 sudo add-apt-repository ppa:juju/stable
99
100=== modified file 'tests/basic_deployment.py'
101--- tests/basic_deployment.py 2015-08-05 01:42:01 +0000
102+++ tests/basic_deployment.py 2015-09-02 02:02:17 +0000
103@@ -12,8 +12,8 @@
104
105 from charmhelpers.contrib.openstack.amulet.utils import (
106 OpenStackAmuletUtils,
107- DEBUG, # flake8: noqa
108- ERROR
109+ DEBUG,
110+ # ERROR
111 )
112
113 # Use DEBUG to turn on debug logging
114@@ -26,8 +26,10 @@
115 def __init__(self, series, openstack=None, source=None, git=False,
116 stable=False):
117 """Deploy the entire test environment."""
118- super(OpenstackDashboardBasicDeployment, self).__init__(series, openstack,
119- source, stable)
120+ super(OpenstackDashboardBasicDeployment, self).__init__(series,
121+ openstack,
122+ source,
123+ stable)
124 self.git = git
125 self._add_services()
126 self._add_relations()
127@@ -36,24 +38,26 @@
128 self._initialize_tests()
129
130 def _add_services(self):
131- """Add services
132-
133- Add the services that we're testing, where openstack-dashboard is local,
134- and the rest of the service are from lp branches that are
135- compatible with the local charm (e.g. stable or next).
136- """
137+ """Add the services that we're testing, where openstack-dashboard is
138+ local, and the rest of the service are from lp branches that are
139+ compatible with the local charm (e.g. stable or next).
140+ """
141 this_service = {'name': 'openstack-dashboard'}
142- other_services = [{'name': 'keystone'}, {'name': 'mysql'}]
143- super(OpenstackDashboardBasicDeployment, self)._add_services(this_service,
144- other_services)
145+ other_services = [{'name': 'keystone'},
146+ {'name': 'mysql'}]
147+ super(OpenstackDashboardBasicDeployment, self)._add_services(
148+ this_service,
149+ other_services)
150
151 def _add_relations(self):
152 """Add all of the relations for the services."""
153 relations = {
154- 'openstack-dashboard:identity-service': 'keystone:identity-service',
155- 'keystone:shared-db': 'mysql:shared-db',
156+ 'openstack-dashboard:identity-service':
157+ 'keystone:identity-service',
158+ 'keystone:shared-db': 'mysql:shared-db',
159 }
160- super(OpenstackDashboardBasicDeployment, self)._add_relations(relations)
161+ super(OpenstackDashboardBasicDeployment, self)._add_relations(
162+ relations)
163
164 def _configure_services(self):
165 """Configure all of the services."""
166@@ -75,16 +79,17 @@
167 {'name': 'requirements',
168 'repository': reqs_repo,
169 'branch': branch},
170- # NOTE(coreycb): Pin oslo libraries here because they're not
171- # capped and recently released versions causing issues for juno.
172+ # NOTE(coreycb): Pin oslo libraries here because
173+ # they're not capped and recently released versions
174+ # causing issues for juno.
175 {'name': 'oslo-config',
176- 'repository': 'git://github.com/openstack/oslo.config',
177+ 'repository': 'git://github.com/openstack/oslo.config', # noqa
178 'branch': '1.6.0'},
179 {'name': 'oslo-i18n',
180 'repository': 'git://github.com/openstack/oslo.i18n',
181 'branch': '1.3.1'},
182 {'name': 'oslo-serialization',
183- 'repository': 'git://github.com/openstack/oslo.serialization',
184+ 'repository': 'git://github.com/openstack/oslo.serialization', # noqa
185 'branch': '1.2.0'},
186 {'name': 'oslo-utils',
187 'repository': 'git://github.com/openstack/oslo.utils',
188@@ -111,7 +116,8 @@
189 'http_proxy': amulet_http_proxy,
190 'https_proxy': amulet_http_proxy,
191 }
192- horizon_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
193+ horizon_config['openstack-origin-git'] = \
194+ yaml.dump(openstack_origin_git)
195
196 keystone_config = {'admin-password': 'openstack',
197 'admin-token': 'ubuntutesting'}
198@@ -119,57 +125,91 @@
199 configs = {'openstack-dashboard': horizon_config,
200 'mysql': mysql_config,
201 'keystone': keystone_config}
202- super(OpenstackDashboardBasicDeployment, self)._configure_services(configs)
203+ super(OpenstackDashboardBasicDeployment, self)._configure_services(
204+ configs)
205
206 def _initialize_tests(self):
207 """Perform final initialization before tests get run."""
208 # Access the sentries for inspecting service units
209 self.keystone_sentry = self.d.sentry.unit['keystone/0']
210- self.openstack_dashboard_sentry = self.d.sentry.unit['openstack-dashboard/0']
211-
212- def test_services(self):
213+ self.openstack_dashboard_sentry = \
214+ self.d.sentry.unit['openstack-dashboard/0']
215+
216+ u.log.debug('openstack release val: {}'.format(
217+ self._get_openstack_release()))
218+ u.log.debug('openstack release str: {}'.format(
219+ self._get_openstack_release_string()))
220+ # Let things settle a bit before moving forward
221+ time.sleep(30)
222+
223+ # NOTE(beisner): Switch to helper once the rabbitmq test refactor lands.
224+ def crude_py_parse(self, file_contents, expected):
225+ for line in file_contents.split('\n'):
226+ if '=' in line:
227+ args = line.split('=')
228+ if len(args) <= 1:
229+ continue
230+ key = args[0].strip()
231+ value = args[1].strip()
232+ if key in expected.keys():
233+ if expected[key] != value:
234+ msg = "Mismatch %s != %s" % (expected[key], value)
235+ amulet.raise_status(amulet.FAIL, msg=msg)
236+
237+ def test_100_services(self):
238 """Verify the expected services are running on the corresponding
239 service units."""
240- dashboard_services = ['service apache2 status']
241-
242- commands = {
243- self.keystone_sentry: ['status keystone'],
244- self.openstack_dashboard_sentry: dashboard_services
245+ services = {
246+ self.keystone_sentry: ['keystone'],
247+ self.openstack_dashboard_sentry: ['apache2']
248 }
249
250- ret = u.validate_services(commands)
251+ ret = u.validate_services_by_name(services)
252 if ret:
253 amulet.raise_status(amulet.FAIL, msg=ret)
254
255- def crude_py_parse(self, file_contents, expected):
256- for line in file_contents.split('\n'):
257- if '=' in line:
258- args = line.split('=')
259- if len(args) <= 1:
260- continue
261- key = args[0].strip()
262- value = args[1].strip()
263- if key in expected.keys():
264- if expected[key] != value:
265- msg="Mismatch %s != %s" % (expected[key], value)
266- amulet.raise_status(amulet.FAIL, msg=msg)
267-
268-
269- def test_local_settings(self):
270+ def test_200_openstack_dashboard_identity_service_relation(self):
271+ """Verify the openstack-dashboard to keystone identity-service
272+ relation data."""
273+ u.log.debug('Checking dashboard:keystone id relation data...')
274 unit = self.openstack_dashboard_sentry
275- ksentry = self.keystone_sentry
276- conf = '/etc/openstack-dashboard/local_settings.py'
277- file_contents = unit.file_contents(conf)
278- rdata = ksentry.relation('identity-service', 'openstack-dashboard:identity-service')
279- expected = {
280- 'LOGIN_REDIRECT_URL': """'/horizon'""",
281- 'OPENSTACK_HOST': '"%s"' % (rdata['private-address']),
282- 'OPENSTACK_KEYSTONE_DEFAULT_ROLE': '"Member"'
283- }
284- self.crude_py_parse(file_contents, expected)
285-
286- def test_router_settings(self):
287- if self.openstack > "icehouse":
288+ relation = ['identity-service', 'keystone:identity-service']
289+ expected = {
290+ 'private-address': u.valid_ip,
291+ 'requested_roles': 'Member',
292+ }
293+
294+ ret = u.validate_relation_data(unit, relation, expected)
295+ if ret:
296+ message = u.relation_error('openstack-dashboard identity-service',
297+ ret)
298+ amulet.raise_status(amulet.FAIL, msg=message)
299+
300+ def test_202_keystone_identity_service_relation(self):
301+ """Verify the keystone to openstack-dashboard identity-service
302+ relation data."""
303+ u.log.debug('Checking keystone:dashboard id relation data...')
304+ unit = self.keystone_sentry
305+ relation = ['identity-service', 'openstack-dashboard:identity-service']
306+ expected = {
307+ 'auth_host': u.valid_ip,
308+ 'auth_port': '35357',
309+ 'auth_protocol': 'http',
310+ 'private-address': u.valid_ip,
311+ 'region': 'RegionOne',
312+ 'service_host': u.valid_ip,
313+ 'service_port': '5000',
314+ 'service_protocol': 'http',
315+ }
316+
317+ ret = u.validate_relation_data(unit, relation, expected)
318+ if ret:
319+ message = u.relation_error('keystone identity-service', ret)
320+ amulet.raise_status(amulet.FAIL, msg=message)
321+
322+ def test_302_router_settings(self):
323+ if self._get_openstack_release() > self.trusty_icehouse:
324+ u.log.debug('Checking dashboard router settings...')
325 unit = self.openstack_dashboard_sentry
326 conf = ('/usr/share/openstack-dashboard/openstack_dashboard/'
327 'enabled/_40_router.py')
328@@ -179,7 +219,8 @@
329 }
330 self.crude_py_parse(file_contents, expected)
331
332- def test_connection(self):
333+ def test_400_connection(self):
334+ u.log.debug('Checking dashboard http response...')
335 unit = self.openstack_dashboard_sentry
336 dashboard_relation = unit.relation('identity-service',
337 'keystone:identity-service')
338@@ -187,59 +228,41 @@
339 response = urllib2.urlopen('http://%s/horizon' % (dashboard_ip))
340 html = response.read()
341 if 'OpenStack Dashboard' not in html:
342- msg="Dashboard frontpage check failed"
343+ msg = "Dashboard frontpage check failed"
344 amulet.raise_status(amulet.FAIL, msg=msg)
345
346- def test_z_restart_on_config_change(self):
347- """Verify that the specified services are restarted when the config
348- is changed.
349-
350- Note(coreycb): The method name with the _z_ is a little odd
351- but it forces the test to run last. It just makes things
352- easier because restarting services requires re-authorization.
353- """
354- conf = '/etc/openstack-dashboard/local_settings.py'
355- services = ['apache2']
356- self.d.configure('openstack-dashboard', {'use-syslog': 'True'})
357- time = 120
358- for s in services:
359- if not u.service_restarted(self.openstack_dashboard_sentry, s, conf,
360- pgrep_full=True, sleep_time=time):
361- self.d.configure('openstack-dashboard', {'use-syslog': 'False'})
362+ def test_900_restart_on_config_change(self):
363+ """Verify that the specified services are restarted when the
364+ config is changed."""
365+
366+ sentry = self.openstack_dashboard_sentry
367+ juju_service = 'openstack-dashboard'
368+
369+ # Expected default and alternate values
370+ set_default = {'use-syslog': 'False'}
371+ set_alternate = {'use-syslog': 'True'}
372+
373+ # Services which are expected to restart upon config change,
374+ # and corresponding config files affected by the change
375+ services = {'apache2': '/etc/openstack-dashboard/local_settings.py'}
376+
377+ # Make config change, check for service restarts
378+ u.log.debug('Making config change on {}...'.format(juju_service))
379+ mtime = u.get_sentry_time(sentry)
380+ self.d.configure(juju_service, set_alternate)
381+
382+ sleep_time = 30
383+ for s, conf_file in services.iteritems():
384+ u.log.debug("Checking that service restarted: {}".format(s))
385+ if not u.validate_service_config_changed(sentry, mtime, s,
386+ conf_file,
387+ retry_count=6,
388+ retry_sleep_time=20,
389+ sleep_time=sleep_time):
390+
391+ self.d.configure(juju_service, set_default)
392 msg = "service {} didn't restart after config change".format(s)
393- time = 0
394- self.d.configure('openstack-dashboard', {'use-syslog': 'False'})
395-
396- def test_openstack_dashboard_identity_service_relation(self):
397- """Verify the openstack-dashboard to keystone identity-service relation data."""
398- unit = self.openstack_dashboard_sentry
399- relation = ['identity-service', 'keystone:identity-service']
400- expected = {
401- 'private-address': u.valid_ip,
402- 'requested_roles': 'Member',
403- }
404-
405- ret = u.validate_relation_data(unit, relation, expected)
406- if ret:
407- message = u.relation_error('openstack-dashboard identity-service', ret)
408- amulet.raise_status(amulet.FAIL, msg=message)
409-
410- def test_keystone_identity_service_relation(self):
411- """Verify the keystone to openstack-dashboard identity-service relation data."""
412- unit = self.keystone_sentry
413- relation = ['identity-service', 'openstack-dashboard:identity-service']
414- expected = {
415- 'auth_host': u.valid_ip,
416- 'auth_port': '35357',
417- 'auth_protocol': 'http',
418- 'private-address': u.valid_ip,
419- 'region': 'RegionOne',
420- 'service_host': u.valid_ip,
421- 'service_port': '5000',
422- 'service_protocol': 'http',
423- }
424-
425- ret = u.validate_relation_data(unit, relation, expected)
426- if ret:
427- message = u.relation_error('keystone identity-service', ret)
428- amulet.raise_status(amulet.FAIL, msg=message)
429+ amulet.raise_status(amulet.FAIL, msg=msg)
430+ sleep_time = 0
431+
432+ self.d.configure(juju_service, set_default)
433
434=== modified file 'tests/charmhelpers/contrib/amulet/utils.py'
435--- tests/charmhelpers/contrib/amulet/utils.py 2015-08-18 17:34:36 +0000
436+++ tests/charmhelpers/contrib/amulet/utils.py 2015-09-02 02:02:17 +0000
437@@ -114,7 +114,7 @@
438 # /!\ DEPRECATION WARNING (beisner):
439 # New and existing tests should be rewritten to use
440 # validate_services_by_name() as it is aware of init systems.
441- self.log.warn('/!\\ DEPRECATION WARNING: use '
442+ self.log.warn('DEPRECATION WARNING: use '
443 'validate_services_by_name instead of validate_services '
444 'due to init system differences.')
445
446@@ -269,33 +269,52 @@
447 """Get last modification time of directory."""
448 return sentry_unit.directory_stat(directory)['mtime']
449
450- def _get_proc_start_time(self, sentry_unit, service, pgrep_full=False):
451- """Get process' start time.
452-
453- Determine start time of the process based on the last modification
454- time of the /proc/pid directory. If pgrep_full is True, the process
455- name is matched against the full command line.
456- """
457- if pgrep_full:
458- cmd = 'pgrep -o -f {}'.format(service)
459- else:
460- cmd = 'pgrep -o {}'.format(service)
461- cmd = cmd + ' | grep -v pgrep || exit 0'
462- cmd_out = sentry_unit.run(cmd)
463- self.log.debug('CMDout: ' + str(cmd_out))
464- if cmd_out[0]:
465- self.log.debug('Pid for %s %s' % (service, str(cmd_out[0])))
466- proc_dir = '/proc/{}'.format(cmd_out[0].strip())
467- return self._get_dir_mtime(sentry_unit, proc_dir)
468+ def _get_proc_start_time(self, sentry_unit, service, pgrep_full=None):
469+ """Get start time of a process based on the last modification time
470+ of the /proc/pid directory.
471+
472+ :sentry_unit: The sentry unit to check for the service on
473+ :service: service name to look for in process table
474+ :pgrep_full: [Deprecated] Use full command line search mode with pgrep
475+ :returns: epoch time of service process start
476+ :param commands: list of bash commands
477+ :param sentry_units: list of sentry unit pointers
478+ :returns: None if successful; Failure message otherwise
479+ """
480+ if pgrep_full is not None:
481+ # /!\ DEPRECATION WARNING (beisner):
482+ # No longer implemented, as pidof is now used instead of pgrep.
483+ # https://bugs.launchpad.net/charm-helpers/+bug/1474030
484+ self.log.warn('DEPRECATION WARNING: pgrep_full bool is no '
485+ 'longer implemented re: lp 1474030.')
486+
487+ pid_list = self.get_process_id_list(sentry_unit, service)
488+ pid = pid_list[0]
489+ proc_dir = '/proc/{}'.format(pid)
490+ self.log.debug('Pid for {} on {}: {}'.format(
491+ service, sentry_unit.info['unit_name'], pid))
492+
493+ return self._get_dir_mtime(sentry_unit, proc_dir)
494
495 def service_restarted(self, sentry_unit, service, filename,
496- pgrep_full=False, sleep_time=20):
497+ pgrep_full=None, sleep_time=20):
498 """Check if service was restarted.
499
500 Compare a service's start time vs a file's last modification time
501 (such as a config file for that service) to determine if the service
502 has been restarted.
503 """
504+ # /!\ DEPRECATION WARNING (beisner):
505+ # This method is prone to races in that no before-time is known.
506+ # Use validate_service_config_changed instead.
507+
508+ # NOTE(beisner) pgrep_full is no longer implemented, as pidof is now
509+ # used instead of pgrep. pgrep_full is still passed through to ensure
510+ # deprecation WARNS. lp1474030
511+ self.log.warn('DEPRECATION WARNING: use '
512+ 'validate_service_config_changed instead of '
513+ 'service_restarted due to known races.')
514+
515 time.sleep(sleep_time)
516 if (self._get_proc_start_time(sentry_unit, service, pgrep_full) >=
517 self._get_file_mtime(sentry_unit, filename)):
518@@ -304,15 +323,15 @@
519 return False
520
521 def service_restarted_since(self, sentry_unit, mtime, service,
522- pgrep_full=False, sleep_time=20,
523- retry_count=2):
524+ pgrep_full=None, sleep_time=20,
525+ retry_count=2, retry_sleep_time=30):
526 """Check if service was been started after a given time.
527
528 Args:
529 sentry_unit (sentry): The sentry unit to check for the service on
530 mtime (float): The epoch time to check against
531 service (string): service name to look for in process table
532- pgrep_full (boolean): Use full command line search mode with pgrep
533+ pgrep_full: [Deprecated] Use full command line search mode with pgrep
534 sleep_time (int): Seconds to sleep before looking for process
535 retry_count (int): If service is not found, how many times to retry
536
537@@ -321,30 +340,44 @@
538 False if service is older than mtime or if service was
539 not found.
540 """
541- self.log.debug('Checking %s restarted since %s' % (service, mtime))
542+ # NOTE(beisner) pgrep_full is no longer implemented, as pidof is now
543+ # used instead of pgrep. pgrep_full is still passed through to ensure
544+ # deprecation WARNS. lp1474030
545+
546+ unit_name = sentry_unit.info['unit_name']
547+ self.log.debug('Checking that %s service restarted since %s on '
548+ '%s' % (service, mtime, unit_name))
549 time.sleep(sleep_time)
550- proc_start_time = self._get_proc_start_time(sentry_unit, service,
551- pgrep_full)
552- while retry_count > 0 and not proc_start_time:
553- self.log.debug('No pid file found for service %s, will retry %i '
554- 'more times' % (service, retry_count))
555- time.sleep(30)
556- proc_start_time = self._get_proc_start_time(sentry_unit, service,
557- pgrep_full)
558- retry_count = retry_count - 1
559+ proc_start_time = None
560+ tries = 0
561+ while tries <= retry_count and not proc_start_time:
562+ try:
563+ proc_start_time = self._get_proc_start_time(sentry_unit,
564+ service,
565+ pgrep_full)
566+ self.log.debug('Attempt {} to get {} proc start time on {} '
567+ 'OK'.format(tries, service, unit_name))
568+ except IOError:
569+ # NOTE(beisner) - race avoidance, proc may not exist yet.
570+ # https://bugs.launchpad.net/charm-helpers/+bug/1474030
571+ self.log.debug('Attempt {} to get {} proc start time on {} '
572+ 'failed'.format(tries, service, unit_name))
573+ time.sleep(retry_sleep_time)
574+ tries += 1
575
576 if not proc_start_time:
577 self.log.warn('No proc start time found, assuming service did '
578 'not start')
579 return False
580 if proc_start_time >= mtime:
581- self.log.debug('proc start time is newer than provided mtime'
582- '(%s >= %s)' % (proc_start_time, mtime))
583+ self.log.debug('Proc start time is newer than provided mtime'
584+ '(%s >= %s) on %s (OK)' % (proc_start_time,
585+ mtime, unit_name))
586 return True
587 else:
588- self.log.warn('proc start time (%s) is older than provided mtime '
589- '(%s), service did not restart' % (proc_start_time,
590- mtime))
591+ self.log.warn('Proc start time (%s) is older than provided mtime '
592+ '(%s) on %s, service did not '
593+ 'restart' % (proc_start_time, mtime, unit_name))
594 return False
595
596 def config_updated_since(self, sentry_unit, filename, mtime,
597@@ -361,12 +394,15 @@
598 bool: True if file was modified more recently than mtime, False if
599 file was modified before mtime,
600 """
601- self.log.debug('Checking %s updated since %s' % (filename, mtime))
602+ self.log.debug('Checking that %s file updated since '
603+ '%s' % (filename, mtime))
604+ unit_name = sentry_unit.info['unit_name']
605 time.sleep(sleep_time)
606 file_mtime = self._get_file_mtime(sentry_unit, filename)
607 if file_mtime >= mtime:
608 self.log.debug('File mtime is newer than provided mtime '
609- '(%s >= %s)' % (file_mtime, mtime))
610+ '(%s >= %s) on %s (OK)' % (file_mtime, mtime,
611+ unit_name))
612 return True
613 else:
614 self.log.warn('File mtime %s is older than provided mtime %s'
615@@ -374,8 +410,9 @@
616 return False
617
618 def validate_service_config_changed(self, sentry_unit, mtime, service,
619- filename, pgrep_full=False,
620- sleep_time=20, retry_count=2):
621+ filename, pgrep_full=None,
622+ sleep_time=20, retry_count=2,
623+ retry_sleep_time=30):
624 """Check service and file were updated after mtime
625
626 Args:
627@@ -383,9 +420,10 @@
628 mtime (float): The epoch time to check against
629 service (string): service name to look for in process table
630 filename (string): The file to check mtime of
631- pgrep_full (boolean): Use full command line search mode with pgrep
632- sleep_time (int): Seconds to sleep before looking for process
633+ pgrep_full: [Deprecated] Use full command line search mode with pgrep
634+ sleep_time (int): Initial sleep in seconds to pass to test helpers
635 retry_count (int): If service is not found, how many times to retry
636+ retry_sleep_time (int): Time in seconds to wait between retries
637
638 Typical Usage:
639 u = OpenStackAmuletUtils(ERROR)
640@@ -402,15 +440,25 @@
641 mtime, False if service is older than mtime or if service was
642 not found or if filename was modified before mtime.
643 """
644- self.log.debug('Checking %s restarted since %s' % (service, mtime))
645- time.sleep(sleep_time)
646- service_restart = self.service_restarted_since(sentry_unit, mtime,
647- service,
648- pgrep_full=pgrep_full,
649- sleep_time=0,
650- retry_count=retry_count)
651- config_update = self.config_updated_since(sentry_unit, filename, mtime,
652- sleep_time=0)
653+
654+ # NOTE(beisner) pgrep_full is no longer implemented, as pidof is now
655+ # used instead of pgrep. pgrep_full is still passed through to ensure
656+ # deprecation WARNS. lp1474030
657+
658+ service_restart = self.service_restarted_since(
659+ sentry_unit, mtime,
660+ service,
661+ pgrep_full=pgrep_full,
662+ sleep_time=sleep_time,
663+ retry_count=retry_count,
664+ retry_sleep_time=retry_sleep_time)
665+
666+ config_update = self.config_updated_since(
667+ sentry_unit,
668+ filename,
669+ mtime,
670+ sleep_time=0)
671+
672 return service_restart and config_update
673
674 def get_sentry_time(self, sentry_unit):
675
676=== added file 'tests/tests.yaml'
677--- tests/tests.yaml 1970-01-01 00:00:00 +0000
678+++ tests/tests.yaml 2015-09-02 02:02:17 +0000
679@@ -0,0 +1,20 @@
680+bootstrap: true
681+reset: true
682+virtualenv: true
683+makefile:
684+ - lint
685+ - test
686+sources:
687+ - ppa:juju/stable
688+packages:
689+ - amulet
690+ - python-amulet
691+ - python-cinderclient
692+ - python-distro-info
693+ - python-glanceclient
694+ - python-heatclient
695+ - python-keystoneclient
696+ - python-neutronclient
697+ - python-novaclient
698+ - python-pika
699+ - python-swiftclient

Subscribers

People subscribed via source and target branches