Port hacluster tests from Amulet to Zaza

Closes-Bug: #1828424
func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/148

Signed-off-by: Xiyue Wang <celia.wang@canonical.com>

Change-Id: I0c0447680f89e2378f9bca3b8322a9bfa50ffd46
This commit is contained in:
Xiyue Wang 2019-12-18 07:07:23 +00:00
parent bb4438cddb
commit df5f114ae1
28 changed files with 363 additions and 608 deletions

View File

@ -1,16 +1,16 @@
#!/usr/bin/make
PYTHON := /usr/bin/env python
PYTHON := /usr/bin/env python3
lint:
@tox -e pep8
test:
@# Starting unit tests
@tox -e py27
@echo Starting unit tests
@tox -e py3
functional_test:
@echo Starting Amulet tests
@tox -e func27
@echo Starting Zaza functional tests
@tox -e func
bin/charm_helpers_sync.py:
@mkdir -p bin

View File

@ -7,23 +7,6 @@ mock>=1.2
flake8>=2.2.4,<=2.4.1
stestr>=2.2.0
requests>=2.18.4
# BEGIN: Amulet OpenStack Charm Helper Requirements
# Liberty client lower constraints
amulet>=1.14.3,<2.0;python_version=='2.7'
bundletester>=0.6.1,<1.0;python_version=='2.7'
python-ceilometerclient>=1.5.0
python-cinderclient>=1.4.0,<5.0 # Train cinderclient removes v1.client
python-glanceclient>=1.1.0
python-heatclient>=0.8.0
python-keystoneclient>=1.7.1
python-neutronclient>=3.1.0
python-novaclient>=2.30.1
python-openstackclient>=1.7.0
python-swiftclient>=2.6.0
pika>=0.10.0,<1.0
distro-info
git+https://github.com/juju/charm-helpers.git#egg=charmhelpers
# END: Amulet OpenStack Charm Helper Requirements
# NOTE: workaround for 14.04 pip/tox
pytz
pyudev # for ceph-* charm unit tests (not mocked?)
git+https://github.com/openstack-charmers/zaza.git#egg=zaza;python_version>='3.0'
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack

View File

@ -1,6 +1,6 @@
# Overview
This directory provides Amulet tests to verify basic deployment functionality
This directory provides Zaza tests to verify basic deployment functionality
from the perspective of this charm, its requirements and its features, as
exercised in a subset of the full OpenStack deployment test bundle topology.

View File

@ -1,286 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import time
import amulet
from charmhelpers.contrib.openstack.amulet.deployment import (
OpenStackAmuletDeployment
)
from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils,
DEBUG,
# ERROR
)
import keystoneclient
from keystoneclient.v2_0 import client as keystone_client
from keystoneclient.v3 import client as keystone_client_v3
# Use DEBUG to turn on debug logging
u = OpenStackAmuletUtils(DEBUG)
seconds_to_wait = 600
# Set number of primary units and cluster-count for hacluster
NUM_UNITS = 3
PY_CRM_GET_PROPERTY = """cd hooks;
python -c 'import pcmk;
try:
print(pcmk.get_property(\"maintenance-mode\"))
except pcmk.PropertyNotFound:
print(\"false\")
'
"""
class HAClusterBasicDeployment(OpenStackAmuletDeployment):
def __init__(self, series=None, openstack=None, source=None, stable=False):
"""Deploy the entire test environment."""
super(HAClusterBasicDeployment, self).__init__(series, openstack,
source, stable)
env_var = 'TEST_VIP'
self._vip = os.getenv(env_var, None)
if not self._vip:
amulet.raise_status(amulet.SKIP, msg="No vip provided with '%s' - "
"skipping tests" % (env_var))
self._add_services()
self._add_relations()
self._configure_services()
self._deploy()
u.log.info('Waiting on extended status checks...')
exclude_services = []
# Wait for deployment ready msgs, except exclusions
self._auto_wait_for_status(exclude_services=exclude_services)
self.d.sentry.wait()
self._initialize_tests()
def _add_services(self):
this_service = {'name': 'hacluster'}
other_services = [
self.get_percona_service_entry(),
{'name': 'keystone', 'units': NUM_UNITS},
]
super(HAClusterBasicDeployment, self)._add_services(this_service,
other_services)
def _add_relations(self):
relations = {'keystone:shared-db': 'percona-cluster:shared-db',
'hacluster:ha': 'keystone:ha'}
super(HAClusterBasicDeployment, self)._add_relations(relations)
def _configure_services(self):
keystone_config = {
'admin-password': 'openstack',
'admin-token': 'ubuntutesting',
'debug': 'true',
'verbose': 'true',
'vip': self._vip,
}
if self._get_openstack_release() >= self.xenial_mitaka:
keystone_config.update({'ha-bindiface': 'ens2'})
pxc_config = {
'dataset-size': '25%',
'max-connections': 1000,
'root-password': 'ChangeMe123',
'sst-password': 'ChangeMe123',
}
hacluster_config = {
'debug': 'true',
'cluster_count': NUM_UNITS,
}
configs = {
'keystone': keystone_config,
'hacluster': hacluster_config,
'percona-cluster': pxc_config,
}
super(HAClusterBasicDeployment, self)._configure_services(configs)
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
self.pxc_sentry = self.d.sentry['percona-cluster'][0]
self.keystone_sentry = self.d.sentry['keystone'][0]
# NOTE: the hacluster unit id may not correspond with its parent unit
# id.
self.hacluster_sentry = self.d.sentry['hacluster'][0]
u.log.debug('openstack release val: {}'.format(
self._get_openstack_release()))
u.log.debug('openstack release str: {}'.format(
self._get_openstack_release_string()))
# Authenticate keystone admin
u.log.debug('Authenticating keystone admin against VIP: '
'{}'.format(self._vip))
#
api_version = 2
client_class = keystone_client.Client
if self._get_openstack_release() >= self.xenial_queens:
api_version = 3
client_class = keystone_client_v3.Client
self.keystone_session, auth = u.get_keystone_session(
self._vip,
api_version=api_version,
username='admin',
password='openstack',
project_name='admin',
user_domain_name='admin_domain',
project_domain_name='admin_domain')
self.keystone = client_class(session=self.keystone_session)
self.keystone.auth_ref = auth.get_access(self.keystone_session)
# Create a demo tenant/role/user
u.log.debug('Creating keystone demo tenant, role and user against '
'VIP: {}'.format(self._vip))
self.demo_tenant = 'demoTenant'
self.demo_role = 'demoRole'
self.demo_user = 'demoUser'
self.demo_project = 'demoProject'
self.demo_domain = 'demoDomain'
if self._get_openstack_release() >= self.xenial_queens:
self.create_users_v3()
self.demo_user_session, auth = u.get_keystone_session(
self._vip,
self.demo_user,
'password',
api_version=3,
user_domain_name=self.demo_domain,
project_domain_name=self.demo_domain,
project_name=self.demo_project
)
self.keystone_demo = keystone_client_v3.Client(
session=self.demo_user_session)
else:
self.create_users_v2()
# Authenticate demo user with keystone (authenticate_keystone_user
# looks up identity-service in service catalogue so uses vip)
self.keystone_demo = \
u.authenticate_keystone_user(
self.keystone, user=self.demo_user,
password='password',
tenant=self.demo_tenant)
def create_users_v3(self):
try:
self.keystone.projects.find(name=self.demo_project)
except keystoneclient.exceptions.NotFound:
domain = self.keystone.domains.create(
self.demo_domain,
description='Demo Domain',
enabled=True
)
project = self.keystone.projects.create(
self.demo_project,
domain,
description='Demo Project',
enabled=True,
)
user = self.keystone.users.create(
self.demo_user,
domain=domain.id,
project=self.demo_project,
password='password',
email='demov3@demo.com',
description='Demo',
enabled=True)
role = self.keystone.roles.find(name='Admin')
self.keystone.roles.grant(
role.id,
user=user.id,
project=project.id)
def create_users_v2(self):
if not u.tenant_exists(self.keystone, self.demo_tenant):
tenant = self.keystone.tenants.create(tenant_name=self.demo_tenant,
description='demo tenant',
enabled=True)
self.keystone.roles.create(name=self.demo_role)
self.keystone.users.create(name=self.demo_user,
password='password',
tenant_id=tenant.id,
email='demo@demo.com')
def _toggle_maintenance_and_wait(self, expected):
SLEEP = 10
TIMEOUT = 900 # secs
crm_get_prop_cmd = PY_CRM_GET_PROPERTY
self.d.configure('hacluster', {'maintenance-mode': expected})
stime = time.time()
ha_unit = self.d.sentry['hacluster'][0]
while time.time() - stime <= TIMEOUT:
time.sleep(SLEEP)
(output, exit_code) = ha_unit.run(crm_get_prop_cmd)
if output == expected:
u.log.debug('maintenance-mode enabled: %s' % output)
break
assert output == expected, 'maintenance-mode is: %s, expected: %s' \
% (output, expected)
def test_900_action_cleanup(self):
"""The services can be cleaned up. """
u.log.debug('Checking cleanup action...')
unit = self.hacluster_sentry
assert u.status_get(unit)[0] == "active"
action_id = u.run_action(unit, "cleanup")
assert u.wait_on_action(action_id), "Cleanup (all) action failed."
assert u.status_get(unit)[0] == "active"
params = {'resource': 'res_ks_haproxy'}
action_id = u.run_action(unit, "cleanup", params)
assert u.wait_on_action(action_id), "Cleanup action w/resource failed."
assert u.status_get(unit)[0] == "active"
u.log.debug('OK')
def test_910_pause_and_resume(self):
"""The services can be paused and resumed. """
u.log.debug('Checking pause and resume actions...')
unit = self.hacluster_sentry
assert u.status_get(unit)[0] == "active"
action_id = u.run_action(unit, "pause")
assert u.wait_on_action(action_id), "Pause action failed."
assert u.status_get(unit)[0] == "maintenance"
action_id = u.run_action(unit, "resume")
assert u.wait_on_action(action_id), "Resume action failed."
assert u.status_get(unit)[0] == "active"
u.log.debug('OK')
def test_920_put_in_maintenance(self):
"""Put pacemaker in maintenance mode"""
return
u.log.debug('Setting cluster in maintenance mode')
self._toggle_maintenance_and_wait('true')
self._toggle_maintenance_and_wait('false')

View File

@ -0,0 +1,31 @@
series: bionic
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

32
tests/bundles/bionic-rocky.yaml Executable file
View File

@ -0,0 +1,32 @@
series: bionic
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:bionic-rocky
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

32
tests/bundles/bionic-stein.yaml Executable file
View File

@ -0,0 +1,32 @@
series: bionic
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:bionic-stein
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

32
tests/bundles/bionic-train.yaml Executable file
View File

@ -0,0 +1,32 @@
series: bionic
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:bionic-train
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

31
tests/bundles/disco-stein.yaml Executable file
View File

@ -0,0 +1,31 @@
series: disco
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

View File

@ -0,0 +1,4 @@
applications:
keystone:
options:
vip: '{{ TEST_VIP00 }}'

View File

@ -0,0 +1,32 @@
series: trusty
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:trusty/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:trusty-mitaka
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

View File

@ -0,0 +1,31 @@
series: xenial
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

32
tests/bundles/xenial-ocata.yaml Executable file
View File

@ -0,0 +1,32 @@
series: xenial
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:xenial-ocata
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

32
tests/bundles/xenial-pike.yaml Executable file
View File

@ -0,0 +1,32 @@
series: xenial
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:xenial-pike
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

View File

@ -0,0 +1,32 @@
series: xenial
machines:
'0':
'1':
'2':
'3':
relations:
- ['keystone:shared-db', 'percona-cluster:shared-db']
- ['hacluster:ha', 'keystone:ha']
applications:
percona-cluster:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 3
options:
openstack-origin: cloud:xenial-queens
token-expiration: 60
to:
- '1'
- '2'
- '3'
hacluster:
charm: ../../../hacluster
subordinate-to:
- keystone

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on cosmic-rocky."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='cosmic')
deployment.run_tests()

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on bionic-queens."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='bionic')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on bionic-rocky."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='bionic',
openstack='cloud:bionic-rocky',
source='cloud:bionic-updates/rocky')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on bionic-stein."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='bionic',
openstack='cloud:bionic-stein',
source='cloud:bionic-stein')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2019 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on bionic-train."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='bionic',
openstack='cloud:bionic-train',
source='cloud:bionic-train')
deployment.run_tests()

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on disco-stein."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='disco')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on trusty-mitaka."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='trusty',
openstack='cloud:trusty-mitaka',
source='cloud:trusty-updates/mitaka')
deployment.run_tests()

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on xenial-mitaka."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='xenial')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on xenial-ocata."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='xenial',
openstack='cloud:xenial-ocata',
source='cloud:xenial-updates/ocata')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on xenial-pike."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='xenial',
openstack='cloud:xenial-pike',
source='cloud:xenial-updates/pike')
deployment.run_tests()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Amulet tests on a basic hacluster deployment on xenial-queens."""
from basic_deployment import HAClusterBasicDeployment
if __name__ == '__main__':
deployment = HAClusterBasicDeployment(series='xenial',
openstack='cloud:xenial-queens',
source='cloud:xenial-updates/queens')
deployment.run_tests()

View File

@ -1,18 +1,23 @@
# Bootstrap the model if necessary.
bootstrap: True
# Re-use bootstrap node.
reset: True
# Use tox/requirements to drive the venv instead of bundletester's venv feature.
virtualenv: False
# Leave makefile empty, otherwise unit/lint tests will rerun ahead of amulet.
makefile: []
# Do not specify juju PPA sources. Juju is presumed to be pre-installed
# and configured in all test runner environments.
#sources:
# Do not specify or rely on system packages.
#packages:
# Do not specify python packages here. Use test-requirements.txt
# and tox instead. ie. The venv is constructed before bundletester
# is invoked.
#python-packages:
reset_timeout: 600
charm_name: hacluster
smoke_bundles:
- bionic-train
gate_bundles:
- trusty-mitaka
- xenial-mitaka
- xenial-ocata
- xenial-pike
- xenial-queens
- bionic-queens
- bionic-rocky
- bionic-stein
- bionic-train
- disco-stein
dev_bundles:
- bionic-train
configure:
- zaza.openstack.charm_tests.keystone.setup.add_demo_user
tests:
- zaza.openstack.charm_tests.hacluster.tests.HaclusterTest

23
tox.ini
View File

@ -1,4 +1,4 @@
# Classic charm (with amulet): ./tox.ini
# Classic charm (with zaza): ./tox.ini
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
@ -15,12 +15,11 @@ skip_missing_interpreters = False
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
CHARM_DIR={envdir}
AMULET_SETUP_TIMEOUT=5400
install_command =
pip install {opts} {packages}
commands = stestr run --slowest {posargs}
whitelist_externals = juju
passenv = HOME TERM AMULET_* CS_* OS_* TEST_*
passenv = HOME TERM CS_* OS_* TEST_*
[testenv:py3]
basepython = python3
@ -83,38 +82,38 @@ commands = {posargs}
[testenv:func-noop]
# DRY RUN - For Debug
basepython = python2.7
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" -n --no-destroy
functest-run-suite --help
[testenv:func]
# Charm Functional Test
# Run all gate tests which are +x (expected to always pass)
basepython = python2.7
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" --no-destroy
functest-run-suite --keep-model
[testenv:func-smoke]
# Charm Functional Test
# Run a specific test as an Amulet smoke test (expected to always pass)
basepython = python2.7
# Run a specific test as an zaza smoke test (expected to always pass)
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bundletester -vl DEBUG -r json -o func-results.json gate-basic-bionic-train --no-destroy
functest-run-suite --keep-model --smoke --log INFO
[testenv:func-dev]
# Charm Functional Test
# Run all development test targets which are +x (may not always pass!)
basepython = python2.7
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "dev-*" --no-destroy
functest-run-suite --keep-model --bundle {posargs}
[flake8]
ignore = E402,E226