diff --git a/src/test-requirements.txt b/src/test-requirements.txt index a4b77a5..d3c9be8 100644 --- a/src/test-requirements.txt +++ b/src/test-requirements.txt @@ -1,33 +1,8 @@ -# This file is managed centrally. If you find the need to modify this as a -# one-off, please don't. Intead, consult #openstack-charms and ask about -# requirements management in charms via bot-control. Thank you. -charm-tools>=2.4.4 -coverage>=3.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' -aodhclient>=0.1.0 -gnocchiclient>=3.1.0,<3.2.0 -python-barbicanclient>=4.0.1 -python-ceilometerclient>=1.5.0 -python-cinderclient>=1.4.0,<5.0.0 -python-designateclient>=1.5 -python-glanceclient>=1.1.0 -python-heatclient>=0.8.0 -python-keystoneclient>=1.7.1 -python-manilaclient>=1.8.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 -pytz # workaround for 14.04 pip/tox -pyudev # for ceph-* charm unit tests (not mocked?) +# 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 *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools +# +# Functional Test Requirements (let Zaza's dependencies solve all dependencies here!) +git+https://github.com/openstack-charmers/zaza.git#egg=zaza +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack diff --git a/src/tests/README.md b/src/tests/README.md index 046be7f..4a386ad 100644 --- a/src/tests/README.md +++ b/src/tests/README.md @@ -1,9 +1,13 @@ # 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. For full details on functional testing of OpenStack charms please refer to -the [functional testing](http://docs.openstack.org/developer/charm-guide/testing.html#functional-testing) -section of the OpenStack Charm Guide. +the [functional testing][charm-guide-functional-testing] section of the +OpenStack Charm Guide. + + + +[charm-guide-functional-testing]: https://docs.openstack.org/charm-guide/latest/testing.html#functional-testing diff --git a/src/tests/basic_deployment.py b/src/tests/basic_deployment.py deleted file mode 100644 index e120230..0000000 --- a/src/tests/basic_deployment.py +++ /dev/null @@ -1,426 +0,0 @@ -import amulet - -import barbicanclient.client as barbican_client -import keystoneclient.exceptions - -from charmhelpers.contrib.openstack.amulet.deployment import ( - OpenStackAmuletDeployment -) - -from charmhelpers.contrib.openstack.amulet.utils import ( - OpenStackAmuletUtils, - DEBUG, -) - -# Use DEBUG to turn on debug logging -u = OpenStackAmuletUtils(DEBUG) - - -class BarbicanBasicDeployment(OpenStackAmuletDeployment): - """Amulet tests on a basic Barbican deployment.""" - - def __init__(self, series, openstack=None, source=None, stable=False): - """Deploy the entire test environment. - """ - super(BarbicanBasicDeployment, self).__init__( - series, openstack, source, stable) - self._add_services() - self._add_relations() - self._configure_services() - self._deploy() - - u.log.info('Waiting on extended status checks...') - exclude_services = [] - self._auto_wait_for_status(exclude_services=exclude_services) - - self.d.sentry.wait() - self._initialize_tests() - - def _add_services(self): - """Add services - - Add the services that we're testing, where barbican is local, - and the rest of the service are from lp branches that are - compatible with the local charm (e.g. stable or next). - """ - this_service = {'name': 'barbican'} - other_services = [ - {'name': 'percona-cluster', 'constraints': {'mem': '3072M'}}, - {'name': 'rabbitmq-server'}, - {'name': 'keystone'} - ] - super(BarbicanBasicDeployment, self)._add_services( - this_service, other_services) - - def _add_relations(self): - """Add all of the relations for the services.""" - relations = { - 'barbican:shared-db': 'percona-cluster:shared-db', - 'barbican:amqp': 'rabbitmq-server:amqp', - 'barbican:identity-service': 'keystone:identity-service', - 'keystone:shared-db': 'percona-cluster:shared-db', - } - super(BarbicanBasicDeployment, self)._add_relations(relations) - - def _configure_services(self): - """Configure all of the services.""" - keystone_config = { - 'admin-password': 'openstack', - } - # say we don't need an HSM for these tests - barbican_config = { - 'require-hsm-plugin': False, - } - pxc_config = { - 'dataset-size': '25%', - 'max-connections': 1000, - 'root-password': 'ChangeMe123', - 'sst-password': 'ChangeMe123', - } - configs = { - 'keystone': keystone_config, - 'barbican': barbican_config, - 'percona-cluster': pxc_config, - } - super(BarbicanBasicDeployment, self)._configure_services(configs) - - def _initialize_tests(self): - """Perform final initialization before tests get run.""" - # Access the sentries for inspecting service units - self.barbican_sentry = self.d.sentry['barbican'][0] - self.pxc_sentry = self.d.sentry['percona-cluster'][0] - self.keystone_sentry = self.d.sentry['keystone'][0] - self.rabbitmq_sentry = self.d.sentry['rabbitmq-server'][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 admin with keystone - self.keystone_session, self.keystone = u.get_default_keystone_session( - self.keystone_sentry, - openstack_release=self._get_openstack_release(), - api_version=3) - - def test_100_services(self): - """Verify the expected services are running on the corresponding - service units.""" - u.log.debug('Checking system services on units...') - - barbican_svcs = [ - 'apache2', 'barbican-worker', - ] - - service_names = { - self.barbican_sentry: barbican_svcs, - } - - ret = u.validate_services_by_name(service_names) - if ret: - amulet.raise_status(amulet.FAIL, msg=ret) - - u.log.debug('OK') - - def test_110_service_catalog(self): - """Verify that the service catalog endpoint data is valid.""" - u.log.debug('Checking keystone service catalog data...') - - actual = self.keystone.service_catalog.get_endpoints() - - # v3 endpoint check - endpoint_check = [ - { - 'id': u.not_null, - 'interface': interface, - 'region': 'RegionOne', - 'region_id': 'RegionOne', - 'url': u.valid_url, - } - for interface in ('admin', 'public', 'internal')] - validate_catalog = u.validate_v3_svc_catalog_endpoint_data - - expected = { - 'key-manager': endpoint_check, - 'identity': endpoint_check, - } - - ret = validate_catalog(expected, actual) - if ret: - amulet.raise_status(amulet.FAIL, msg=ret) - - u.log.debug('OK') - - def test_114_barbican_api_endpoint(self): - """Verify the barbican api endpoint data.""" - u.log.debug('Checking barbican api endpoint data...') - endpoints = self.keystone.endpoints.list() - u.log.debug(endpoints) - admin_port = '9312' - internal_port = public_port = '9311' - # For keystone v3 it's slightly different. - expected = {'id': u.not_null, - 'region': 'RegionOne', - 'region_id': 'RegionOne', - 'url': u.valid_url, - 'interface': u.not_null, # we match this in the test - 'service_id': u.not_null} - - ret = u.validate_v3_endpoint_data( - endpoints, admin_port, internal_port, public_port, expected) - - if ret: - message = 'barbican endpoint: {}'.format(ret) - amulet.raise_status(amulet.FAIL, msg=message) - - u.log.debug('OK') - - def test_200_barbican_identity_relation(self): - """Verify the barbican to keystone identity-service relation data""" - u.log.debug('Checking barbican to keystone identity-service ' - 'relation data...') - unit = self.barbican_sentry - relation = ['identity-service', 'keystone:identity-service'] - barbican_ip = unit.relation(*relation)['private-address'] - barbican_admin_endpoint = "http://%s:9312" % (barbican_ip) - barbican_endpoint = "http://%s:9311" % (barbican_ip) - - expected = { - 'admin_url': barbican_admin_endpoint, - 'internal_url': barbican_endpoint, - 'private-address': barbican_ip, - 'public_url': barbican_endpoint, - 'region': 'RegionOne', - 'service': 'barbican', - } - - ret = u.validate_relation_data(unit, relation, expected) - if ret: - message = u.relation_error('barbican identity-service', ret) - amulet.raise_status(amulet.FAIL, msg=message) - - u.log.debug('OK') - - def test_201_keystone_barbican_identity_relation(self): - """Verify the keystone to barbican identity-service relation data""" - u.log.debug('Checking keystone:barbican identity relation data...') - unit = self.keystone_sentry - relation = ['identity-service', 'barbican:identity-service'] - id_relation = unit.relation(*relation) - id_ip = id_relation['private-address'] - expected = { - 'auth_host': id_ip, - 'auth_port': "35357", - 'auth_protocol': 'http', - 'private-address': id_ip, - 'service_host': id_ip, - 'service_password': u.not_null, - 'service_port': "5000", - 'service_protocol': 'http', - 'service_tenant': 'services', - 'service_tenant_id': u.not_null, - 'service_username': 'barbican', - } - ret = u.validate_relation_data(unit, relation, expected) - if ret: - message = u.relation_error('keystone identity-service', ret) - amulet.raise_status(amulet.FAIL, msg=message) - - u.log.debug('OK') - - def test_203_barbican_amqp_relation(self): - """Verify the barbican to rabbitmq-server amqp relation data""" - u.log.debug('Checking barbican:rabbitmq amqp relation data...') - unit = self.barbican_sentry - relation = ['amqp', 'rabbitmq-server:amqp'] - expected = { - 'username': 'barbican', - 'private-address': u.valid_ip, - 'vhost': 'openstack' - } - - ret = u.validate_relation_data(unit, relation, expected) - if ret: - message = u.relation_error('barbican amqp', ret) - amulet.raise_status(amulet.FAIL, msg=message) - - u.log.debug('OK') - - def test_204_barbican_amqp_relation(self): - """Verify the rabbitmq-server to barbican amqp relation data""" - u.log.debug('Checking rabbitmq:barbican barbican relation data...') - unit = self.rabbitmq_sentry - relation = ['amqp', 'barbican:amqp'] - expected = { - 'hostname': u.valid_ip, - 'private-address': u.valid_ip, - 'password': u.not_null, - } - - ret = u.validate_relation_data(unit, relation, expected) - if ret: - message = u.relation_error('rabbitmq barbican', ret) - amulet.raise_status(amulet.FAIL, msg=message) - - u.log.debug('OK') - - @staticmethod - def _find_or_create(items, key, create): - """Find or create the thing in the items - - :param items: the items to search using the key - :param key: a function that key(item) -> boolean if found. - :param create: a function to call if the key() never was true. - :returns: the item that was either found or created. - """ - for i in items: - if key(i): - return i - return create() - - def test_400_api_connection(self): - """Simple api calls to check service is up and responding""" - u.log.debug('Checking api functionality...') - - # This handles both keystone v2 and v3. - # For keystone v2 we need a user: - # - 'demo' user - # - has a project 'demo' - # - in the 'demo' project - # - with an 'admin' role - # For keystone v3 we need a user: - # - 'default' domain - # - 'demo' user - # - 'demo' project - # - 'admin' role -- to be able to delete. - - # barbican requires a user with creator or admin role on the project - # when creating a secret (which this test does). Therefore, we create - # a demo user, demo project, and then get a demo barbican client and do - # the secret. ensure that the default domain is created. - - # find or create the 'default' domain - domain = self._find_or_create( - items=self.keystone.domains.list(), - key=lambda u: u.name.lower() == 'default', - create=lambda: self.keystone.domains.create( - "default", - description="domain for barbican testing", - enabled=True)) - # find or create the 'demo' user - demo_user = self._find_or_create( - items=self.keystone.users.list(domain=domain.id), - key=lambda u: u.name == 'demo', - create=lambda: self.keystone.users.create( - 'demo', - domain=domain.id, - description="Demo user for barbican tests", - enabled=True, - email="demo@example.com", - password="pass")) - # find or create the 'demo' project - demo_project = self._find_or_create( - items=self.keystone.projects.list(domain=domain.id), - key=lambda x: x.name == 'demo', - create=lambda: self.keystone.projects.create( - 'demo', - domain=domain.id, - description='barbican testing project', - enabled=True)) - # create the role for the user - needs to be admin so that the - # secret can be deleted - note there is only one admin role, and it - # should already be created - if not, then this will fail later. - admin_role = self._find_or_create( - items=self.keystone.roles.list(), - key=lambda r: r.name.lower() == 'admin', - create=lambda: None) - # now grant the creator role to the demo user. - try: - self.keystone.roles.check( - role=admin_role, - user=demo_user, - project=demo_project) - except keystoneclient.exceptions.NotFound: - # create it if it isn't found - self.keystone.roles.grant( - role=admin_role, - user=demo_user, - project=demo_project) - keystone_ip = self.keystone_sentry.info['public-address'] - self.keystone_demo = u.authenticate_keystone( - keystone_ip, demo_user.name, 'pass', api_version=3, - user_domain_name=domain.name, - project_domain_name=domain.name, - project_name=demo_project.name) - - # Authenticate admin with barbican endpoint - barbican_ep = self.keystone.service_catalog.url_for( - service_type='key-manager', interface='publicURL') - barbican = barbican_client.Client(session=self.keystone_demo.session, - endpoint=barbican_ep) - # now create the secret. - my_secret = barbican.secrets.create() - my_secret.name = u'Random plain text password' - my_secret.payload = u'password' - my_secret_ref = my_secret.store() - assert(my_secret_ref is not None) - # and now delete the secret - my_secret.delete() - u.log.debug('OK') - - def test_900_restart_on_config_change(self): - """Verify that the specified services are restarted when the config - is changed. - """ - sentry = self.barbican_sentry - juju_service = 'barbican' - - # Expected default and alternate values - set_default = {'debug': 'False'} - set_alternate = {'debug': 'True'} - - # Services which are expected to restart upon config change, - # and corresponding config files affected by the change - conf_file = '/etc/barbican/barbican.conf' - services = { - 'barbican-worker': conf_file, - } - - # Make config change, check for service restarts - u.log.debug('Making config change on {}...'.format(juju_service)) - mtime = u.get_sentry_time(sentry) - self.d.configure(juju_service, set_alternate) - - sleep_time = 40 - for s, conf_file in services.iteritems(): - u.log.debug("Checking that service restarted: {}".format(s)) - if not u.validate_service_config_changed(sentry, mtime, s, - conf_file, - retry_count=4, - retry_sleep_time=20, - sleep_time=sleep_time): - self.d.configure(juju_service, set_default) - msg = "service {} didn't restart after config change".format(s) - amulet.raise_status(amulet.FAIL, msg=msg) - sleep_time = 0 - - self.d.configure(juju_service, set_default) - u.log.debug('OK') - - def _assert_services(self, should_run): - services = ('barbican-worker', ) - u.get_unit_process_ids( - {self.barbican_sentry: services}, - expect_success=should_run) - - def test_910_pause_and_resume(self): - """The services can be paused and resumed. """ - self._assert_services(should_run=True) - action_id = u.run_action(self.barbican_sentry, "pause") - assert u.wait_on_action(action_id), "Pause action failed." - - self._assert_services(should_run=False) - - action_id = u.run_action(self.barbican_sentry, "resume") - assert u.wait_on_action(action_id), "Resume action failed" - self._assert_services(should_run=True) - u.log.debug('OK') diff --git a/src/tests/bundles/bionic-rocky.yaml b/src/tests/bundles/bionic-rocky.yaml new file mode 100644 index 0000000..2e79490 --- /dev/null +++ b/src/tests/bundles/bionic-rocky.yaml @@ -0,0 +1,50 @@ +series: bionic + +machines: + '0': + constraints: mem=3072M + '1': + '2': + '3': + +applications: + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + to: + - '0' + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + to: + - '1' + + barbican: + series: bionic + charm: ../../../barbican + num_units: 1 + options: + openstack-origin: cloud:bionic-rocky + debug: true + to: + - '2' + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + to: + - '3' + +relations: +- - mysql:shared-db + - keystone:shared-db +- - mysql:shared-db + - barbican:shared-db +- - keystone:identity-service + - barbican:identity-service +- - rabbitmq-server:amqp + - barbican:amqp diff --git a/src/tests/bundles/bionic-stein.yaml b/src/tests/bundles/bionic-stein.yaml new file mode 100644 index 0000000..d869251 --- /dev/null +++ b/src/tests/bundles/bionic-stein.yaml @@ -0,0 +1,50 @@ +series: bionic + +machines: + '0': + constraints: mem=3072M + '1': + '2': + '3': + +applications: + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + to: + - '0' + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:bionic-stein + to: + - '1' + + barbican: + series: bionic + charm: ../../../barbican + num_units: 1 + options: + openstack-origin: cloud:bionic-stein + debug: true + to: + - '2' + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + to: + - '3' + +relations: +- - mysql:shared-db + - keystone:shared-db +- - mysql:shared-db + - barbican:shared-db +- - keystone:identity-service + - barbican:identity-service +- - rabbitmq-server:amqp + - barbican:amqp diff --git a/src/tests/bundles/bionic-train.yaml b/src/tests/bundles/bionic-train.yaml new file mode 100644 index 0000000..dd930de --- /dev/null +++ b/src/tests/bundles/bionic-train.yaml @@ -0,0 +1,50 @@ +series: bionic + +machines: + '0': + constraints: mem=3072M + '1': + '2': + '3': + +applications: + + mysql: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + to: + - '0' + + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: cloud:bionic-train + to: + - '1' + + barbican: + series: bionic + charm: ../../../barbican + num_units: 1 + options: + openstack-origin: cloud:bionic-train + debug: true + to: + - '2' + + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + to: + - '3' + +relations: +- - mysql:shared-db + - keystone:shared-db +- - mysql:shared-db + - barbican:shared-db +- - keystone:identity-service + - barbican:identity-service +- - rabbitmq-server:amqp + - barbican:amqp diff --git a/src/tests/gate-basic-bionic-rocky b/src/tests/gate-basic-bionic-rocky deleted file mode 100755 index d3d87bc..0000000 --- a/src/tests/gate-basic-bionic-rocky +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -"""Amulet tests on a basic barbican deploy on bionic-rocky for keystone v3. -""" - -from basic_deployment import BarbicanBasicDeployment - -if __name__ == '__main__': - deployment = BarbicanBasicDeployment(series='bionic', - openstack='cloud:bionic-rocky', - source='cloud:bionic-updates/rocky') - deployment.run_tests() diff --git a/src/tests/gate-basic-bionic-stein b/src/tests/gate-basic-bionic-stein deleted file mode 100755 index 2ca8613..0000000 --- a/src/tests/gate-basic-bionic-stein +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -"""Amulet tests on a basic barbican deploy on bionic-stein for keystone v3. -""" - -from basic_deployment import BarbicanBasicDeployment - -if __name__ == '__main__': - deployment = BarbicanBasicDeployment(series='bionic', - openstack='cloud:bionic-stein', - source='cloud:bionic-stein') - deployment.run_tests() diff --git a/src/tests/gate-basic-bionic-train b/src/tests/gate-basic-bionic-train deleted file mode 100755 index 706f2f5..0000000 --- a/src/tests/gate-basic-bionic-train +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -"""Amulet tests on a basic barbican deploy on bionic-train for keystone v3. -""" - -from basic_deployment import BarbicanBasicDeployment - -if __name__ == '__main__': - deployment = BarbicanBasicDeployment(series='bionic', - openstack='cloud:bionic-train', - source='cloud:bionic-train') - deployment.run_tests() diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml index a03e7ba..2820a0d 100644 --- a/src/tests/tests.yaml +++ b/src/tests/tests.yaml @@ -1,18 +1,9 @@ -# 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: barbican +smoke_bundles: +- bionic-train +gate_bundles: +- bionic-train +- bionic-stein +- bionic-rocky +tests: +- zaza.openstack.charm_tests.barbican.tests.BarbicanTest diff --git a/src/tox.ini b/src/tox.ini index dd17ae5..07a7adc 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -1,4 +1,4 @@ -# Source charm (with amulet): ./src/tox.ini +# Source charm (with zaza): ./src/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,41 +15,36 @@ skip_missing_interpreters = False [testenv] setenv = VIRTUAL_ENV={envdir} PYTHONHASHSEED=0 - CHARM_DIR={envdir} - AMULET_SETUP_TIMEOUT=5400 whitelist_externals = juju -passenv = HOME TERM AMULET_* CS_* OS_* TEST_* +passenv = HOME TERM CS_* OS_* TEST_* deps = -r{toxinidir}/test-requirements.txt install_command = pip install {opts} {packages} [testenv:pep8] basepython = python3 +deps=charm-tools commands = charm-proof [testenv:func-noop] -# DRY RUN - For Debug -basepython = python2.7 +basepython = python3 commands = - bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" -n --no-destroy + functest-run-suite --help [testenv:func] -# Run all gate tests which are +x (expected to always pass) -basepython = python2.7 +basepython = python3 commands = - bundletester -vl DEBUG -r json -o func-results.json --test-pattern "gate-*" --no-destroy + functest-run-suite --keep-model [testenv:func-smoke] -# Run a specific test as an Amulet smoke test (expected to always pass) -basepython = python2.7 +basepython = python3 commands = - bundletester -vl DEBUG -r json -o func-results.json gate-basic-bionic-train --no-destroy + functest-run-suite --keep-model --smoke -[testenv:func-dev] -# Run all development test targets which are +x (may not always pass!) -basepython = python2.7 +[testenv:func-target] +basepython = python3 commands = - bundletester -vl DEBUG -r json -o func-results.json --test-pattern "dev-*" --no-destroy + functest-run-suite --keep-model --bundle {posargs} [testenv:venv] commands = {posargs} diff --git a/test-requirements.txt b/test-requirements.txt index 14b380e..0ab97f6 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,7 @@ -# This file is managed centrally. If you find the need to modify this as a -# one-off, please don't. Intead, consult #openstack-charms and ask about -# requirements management in charms via bot-control. Thank you. +# 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 *requirements.txt files for OpenStack Charms: +# https://github.com/openstack-charmers/release-tools # # Lint and unit test requirements flake8>=2.2.4,<=2.4.1 @@ -11,3 +12,12 @@ mock>=1.2 nose>=1.3.7 coverage>=3.6 git+https://github.com/openstack/charms.openstack.git#egg=charms.openstack +# +# Revisit for removal / mock improvement: +netifaces # vault +psycopg2-binary # vault +tenacity # vault +pbr # vault +cryptography # vault, keystone-saml-mellon +lxml # keystone-saml-mellon +hvac # vault, barbican-vault diff --git a/tox.ini b/tox.ini index 5b41c1d..afd48f0 100644 --- a/tox.ini +++ b/tox.ini @@ -50,6 +50,11 @@ basepython = python3.7 deps = -r{toxinidir}/test-requirements.txt commands = stestr run --slowest {posargs} +[testenv:py38] +basepython = python3.8 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run --slowest {posargs} + [testenv:pep8] basepython = python3 deps = -r{toxinidir}/test-requirements.txt