From 49acd2f3f3105eadbd75fd974fac3f812e273ee4 Mon Sep 17 00:00:00 2001 From: Ryan Beisner Date: Thu, 22 Sep 2016 17:59:32 +0000 Subject: [PATCH] Update amulet test definitions for Newton - Remove Precise-Icehouse Amulet test definitions if they exist. - Add Xenial-Newton Amulet test definitions, using ODL BE. - Add Yakkety-Newton Amulet test definitions, using ODL BE. - Use the percona-cluster charm in tests instead of the mysql charm. - Also adjust py hash bangs to use env python. Closes-Bug: 1632533 Change-Id: If10e49a9c45bc7fcd1eb073dcdccabed6c37a958 --- .project | 17 +++ .../contrib/openstack/amulet/deployment.py | 2 +- .../contrib/openstack/amulet/utils.py | 11 +- hooks/charmhelpers/contrib/openstack/utils.py | 5 +- tests/basic_deployment.py | 106 +++++++++++++----- .../contrib/openstack/amulet/deployment.py | 2 +- .../contrib/openstack/amulet/utils.py | 11 +- tests/gate-basic-trusty-icehouse | 2 +- tests/gate-basic-trusty-kilo | 2 +- tests/gate-basic-trusty-liberty | 2 +- tests/gate-basic-trusty-mitaka | 2 +- tests/gate-basic-xenial-mitaka | 2 +- tests/gate-basic-xenial-newton | 26 +++++ tests/gate-basic-yakkety-newton | 24 ++++ tests/tests.yaml | 2 +- 15 files changed, 166 insertions(+), 50 deletions(-) create mode 100644 .project create mode 100755 tests/gate-basic-xenial-newton create mode 100644 tests/gate-basic-yakkety-newton diff --git a/.project b/.project new file mode 100644 index 0000000..435dd5a --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + odl-controller + + + + + + org.python.pydev.PyDevBuilder + + + + + + org.python.pydev.pythonNature + + diff --git a/hooks/charmhelpers/contrib/openstack/amulet/deployment.py b/hooks/charmhelpers/contrib/openstack/amulet/deployment.py index 6fe8cf8..9e0b07f 100644 --- a/hooks/charmhelpers/contrib/openstack/amulet/deployment.py +++ b/hooks/charmhelpers/contrib/openstack/amulet/deployment.py @@ -156,7 +156,7 @@ class OpenStackAmuletDeployment(AmuletDeployment): use_source = list(set( use_source + ['mysql', 'mongodb', 'rabbitmq-server', 'ceph', 'ceph-osd', 'ceph-radosgw', 'ceph-mon', - 'ceph-proxy'])) + 'ceph-proxy', 'percona-cluster', 'lxd'])) # Charms which can not use openstack-origin, ie. many subordinates no_origin = list(set( diff --git a/hooks/charmhelpers/contrib/openstack/amulet/utils.py b/hooks/charmhelpers/contrib/openstack/amulet/utils.py index 24b353e..e4546c8 100644 --- a/hooks/charmhelpers/contrib/openstack/amulet/utils.py +++ b/hooks/charmhelpers/contrib/openstack/amulet/utils.py @@ -306,10 +306,8 @@ class OpenStackAmuletUtils(AmuletUtils): password, tenant): """Authenticates admin user with cinder.""" # NOTE(beisner): cinder python client doesn't accept tokens. - service_ip = \ - keystone_sentry.relation('shared-db', - 'mysql:shared-db')['private-address'] - ept = "http://{}:5000/v2.0".format(service_ip.strip().decode('utf-8')) + keystone_ip = keystone_sentry.info['public-address'] + ept = "http://{}:5000/v2.0".format(keystone_ip.strip().decode('utf-8')) return cinder_client.Client(username, password, tenant, ept) def authenticate_keystone_admin(self, keystone_sentry, user, password, @@ -317,10 +315,9 @@ class OpenStackAmuletUtils(AmuletUtils): keystone_ip=None): """Authenticates admin user with the keystone admin endpoint.""" self.log.debug('Authenticating keystone admin...') - unit = keystone_sentry if not keystone_ip: - keystone_ip = unit.relation('shared-db', - 'mysql:shared-db')['private-address'] + keystone_ip = keystone_sentry.info['public-address'] + base_ep = "http://{}:35357".format(keystone_ip.strip().decode('utf-8')) if not api_version or api_version == 2: ep = base_ep + "/v2.0" diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index 9abd4c3..8c89c3a 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -229,6 +229,7 @@ GIT_DEFAULT_REPOS = { GIT_DEFAULT_BRANCHES = { 'liberty': 'stable/liberty', 'mitaka': 'stable/mitaka', + 'newton': 'stable/newton', 'master': 'master', } @@ -735,12 +736,12 @@ def git_os_codename_install_source(projects_yaml): if projects in GIT_DEFAULT_BRANCHES.keys(): if projects == 'master': - return 'newton' + return 'ocata' return projects if 'release' in projects: if projects['release'] == 'master': - return 'newton' + return 'ocata' return projects['release'] return None diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 2822d41..621907c 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# # Copyright 2016 Canonical Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,8 +27,25 @@ from charmhelpers.contrib.openstack.amulet.utils import ( # ERROR ) +from novaclient import exceptions + + +class NovaOpenStackAmuletUtils(OpenStackAmuletUtils): + """Nova based helper extending base helper for creation of flavors""" + + def create_flavor(self, nova, name, ram, vcpus, disk, flavorid="auto", + ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True): + """Create the specified flavor.""" + try: + nova.flavors.find(name=name) + except (exceptions.NotFound, exceptions.NoUniqueMatch): + self.log.debug('Creating flavor ({})'.format(name)) + nova.flavors.create(name, ram, vcpus, disk, flavorid, + ephemeral, swap, rxtx_factor, is_public) + + # Use DEBUG to turn on debug logging -u = OpenStackAmuletUtils(DEBUG) +u = NovaOpenStackAmuletUtils(DEBUG) ODL_PROFILES = { 'helium': { @@ -61,8 +76,9 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): self._add_relations() self._configure_services() self._deploy() - exclude_services = ['mysql', 'odl-controller', 'neutron-api-odl'] + exclude_services = ['odl-controller', 'neutron-api-odl'] self._auto_wait_for_status(exclude_services=exclude_services) + self.d.sentry.wait() self._initialize_tests() def _add_services(self): @@ -77,7 +93,7 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): 'constraints': {'mem': '8G'}, } other_services = [ - {'name': 'mysql'}, + {'name': 'percona-cluster', 'constraints': {'mem': '3072M'}}, {'name': 'rabbitmq-server'}, {'name': 'keystone'}, {'name': 'nova-cloud-controller'}, @@ -95,15 +111,15 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): def _add_relations(self): """Add all of the relations for the services.""" relations = { - 'keystone:shared-db': 'mysql:shared-db', + 'keystone:shared-db': 'percona-cluster:shared-db', 'neutron-gateway:amqp': 'rabbitmq-server:amqp', 'nova-cloud-controller:quantum-network-service': 'neutron-gateway:quantum-network-service', - 'nova-cloud-controller:shared-db': 'mysql:shared-db', + 'nova-cloud-controller:shared-db': 'percona-cluster:shared-db', 'nova-cloud-controller:identity-service': 'keystone:' 'identity-service', 'nova-cloud-controller:amqp': 'rabbitmq-server:amqp', - 'neutron-api:shared-db': 'mysql:shared-db', + 'neutron-api:shared-db': 'percona-cluster:shared-db', 'neutron-api:amqp': 'rabbitmq-server:amqp', 'neutron-api:neutron-api': 'nova-cloud-controller:neutron-api', 'neutron-api:identity-service': 'keystone:identity-service', @@ -113,10 +129,10 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): 'openvswitch-odl:ovsdb-manager': 'odl-controller:ovsdb-manager', 'neutron-api-odl:odl-controller': 'odl-controller:controller-api', 'glance:identity-service': 'keystone:identity-service', - 'glance:shared-db': 'mysql:shared-db', + 'glance:shared-db': 'percona-cluster:shared-db', 'glance:amqp': 'rabbitmq-server:amqp', 'nova-compute:image-service': 'glance:image-service', - 'nova-compute:shared-db': 'mysql:shared-db', + 'nova-compute:shared-db': 'percona-cluster:shared-db', 'nova-compute:amqp': 'rabbitmq-server:amqp', 'nova-cloud-controller:cloud-compute': 'nova-compute:' 'cloud-compute', @@ -126,11 +142,18 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): def _configure_services(self): """Configure all of the services.""" - neutron_gateway_config = {'plugin': 'ovs-odl', - 'instance-mtu': '1400'} - neutron_api_config = {'neutron-security-groups': 'True', - 'manage-neutron-plugin-legacy-mode': 'False'} - neutron_api_odl_config = {'overlay-network-type': 'vxlan gre'} + neutron_gateway_config = { + 'plugin': 'ovs-odl', + 'instance-mtu': '1400', + } + neutron_api_config = { + 'neutron-security-groups': 'True', + 'manage-neutron-plugin-legacy-mode': 'False', + } + neutron_api_odl_config = { + 'overlay-network-type': 'vxlan gre', + } + odl_controller_config = {} if os.environ.get(ODL_PROFILES[self.odl_version]['location']): odl_controller_config['install-url'] = \ @@ -143,21 +166,35 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): os.environ['AMULET_HTTP_PROXY'] odl_controller_config['profile'] = \ ODL_PROFILES[self.odl_version]['profile'] - keystone_config = {'admin-password': 'openstack', - 'admin-token': 'ubuntutesting'} - nova_cc_config = {'network-manager': 'Neutron'} - configs = {'neutron-gateway': neutron_gateway_config, - 'neutron-api': neutron_api_config, - 'neutron-api-odl': neutron_api_odl_config, - 'odl-controller': odl_controller_config, - 'keystone': keystone_config, - 'nova-cloud-controller': nova_cc_config} + + keystone_config = { + 'admin-password': 'openstack', + 'admin-token': 'ubuntutesting' + } + nova_cc_config = { + 'network-manager': 'Neutron' + } + pxc_config = { + 'dataset-size': '25%', + 'max-connections': 1000, + 'root-password': 'ChangeMe123', + 'sst-password': 'ChangeMe123', + } + configs = { + 'neutron-gateway': neutron_gateway_config, + 'neutron-api': neutron_api_config, + 'neutron-api-odl': neutron_api_odl_config, + 'odl-controller': odl_controller_config, + 'keystone': keystone_config, + 'nova-cloud-controller': nova_cc_config, + 'percona-cluster': pxc_config, + } super(ODLControllerBasicDeployment, self)._configure_services(configs) def _initialize_tests(self): """Perform final initialization before tests get run.""" # Access the sentries for inspecting service units - self.mysql_sentry = self.d.sentry['mysql'][0] + self.pxc_sentry = self.d.sentry['percona-cluster'][0] self.keystone_sentry = self.d.sentry['keystone'][0] self.rmq_sentry = self.d.sentry['rabbitmq-server'][0] self.nova_cc_sentry = self.d.sentry['nova-cloud-controller'][0] @@ -172,7 +209,6 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): user='admin', password='openstack', tenant='admin') - # Authenticate admin with neutron ep = self.keystone.service_catalog.url_for(service_type='identity', endpoint_type='publicURL') @@ -209,6 +245,12 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): password='password', tenant=self.demo_tenant) + # Authenticate admin with nova endpoint + self.nova = u.authenticate_nova_user(self.keystone, + user='admin', + password='openstack', + tenant='admin') + def test_100_services(self): """Verify the expected services are running on the corresponding service units.""" @@ -225,6 +267,14 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): self.odl_controller_sentry: odl_c_services, } + if self._get_openstack_release() >= self.xenial_newton: + commands[self.neutron_gateway_sentry].remove( + 'neutron-lbaas-agent' + ) + commands[self.neutron_gateway_sentry].append( + 'neutron-lbaasv2-agent' + ) + ret = u.validate_services_by_name(commands) if ret: amulet.raise_status(amulet.FAIL, msg=ret) @@ -461,6 +511,10 @@ class ODLControllerBasicDeployment(OpenStackAmuletDeployment): if not image: amulet.raise_status(amulet.FAIL, msg="Image create failed") + # NOTE(jamespage): ensure require flavor exists, required for >= newton + u.create_flavor(nova=self.nova, + name='m1.tiny', ram=512, vcpus=1, disk=1) + instance = u.create_instance(self.nova_demo, "cirros-image", "cirros", "m1.tiny") if not instance: diff --git a/tests/charmhelpers/contrib/openstack/amulet/deployment.py b/tests/charmhelpers/contrib/openstack/amulet/deployment.py index 6fe8cf8..9e0b07f 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/deployment.py +++ b/tests/charmhelpers/contrib/openstack/amulet/deployment.py @@ -156,7 +156,7 @@ class OpenStackAmuletDeployment(AmuletDeployment): use_source = list(set( use_source + ['mysql', 'mongodb', 'rabbitmq-server', 'ceph', 'ceph-osd', 'ceph-radosgw', 'ceph-mon', - 'ceph-proxy'])) + 'ceph-proxy', 'percona-cluster', 'lxd'])) # Charms which can not use openstack-origin, ie. many subordinates no_origin = list(set( diff --git a/tests/charmhelpers/contrib/openstack/amulet/utils.py b/tests/charmhelpers/contrib/openstack/amulet/utils.py index 24b353e..e4546c8 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/utils.py +++ b/tests/charmhelpers/contrib/openstack/amulet/utils.py @@ -306,10 +306,8 @@ class OpenStackAmuletUtils(AmuletUtils): password, tenant): """Authenticates admin user with cinder.""" # NOTE(beisner): cinder python client doesn't accept tokens. - service_ip = \ - keystone_sentry.relation('shared-db', - 'mysql:shared-db')['private-address'] - ept = "http://{}:5000/v2.0".format(service_ip.strip().decode('utf-8')) + keystone_ip = keystone_sentry.info['public-address'] + ept = "http://{}:5000/v2.0".format(keystone_ip.strip().decode('utf-8')) return cinder_client.Client(username, password, tenant, ept) def authenticate_keystone_admin(self, keystone_sentry, user, password, @@ -317,10 +315,9 @@ class OpenStackAmuletUtils(AmuletUtils): keystone_ip=None): """Authenticates admin user with the keystone admin endpoint.""" self.log.debug('Authenticating keystone admin...') - unit = keystone_sentry if not keystone_ip: - keystone_ip = unit.relation('shared-db', - 'mysql:shared-db')['private-address'] + keystone_ip = keystone_sentry.info['public-address'] + base_ep = "http://{}:35357".format(keystone_ip.strip().decode('utf-8')) if not api_version or api_version == 2: ep = base_ep + "/v2.0" diff --git a/tests/gate-basic-trusty-icehouse b/tests/gate-basic-trusty-icehouse index ff9aa9d..5e2257d 100755 --- a/tests/gate-basic-trusty-icehouse +++ b/tests/gate-basic-trusty-icehouse @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-kilo b/tests/gate-basic-trusty-kilo index dfe1003..9144714 100755 --- a/tests/gate-basic-trusty-kilo +++ b/tests/gate-basic-trusty-kilo @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-liberty b/tests/gate-basic-trusty-liberty index acca0d9..d36715b 100755 --- a/tests/gate-basic-trusty-liberty +++ b/tests/gate-basic-trusty-liberty @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-mitaka b/tests/gate-basic-trusty-mitaka index f56100a..7b1bf5f 100755 --- a/tests/gate-basic-trusty-mitaka +++ b/tests/gate-basic-trusty-mitaka @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-xenial-mitaka b/tests/gate-basic-xenial-mitaka index 05f37cd..8d6cda6 100755 --- a/tests/gate-basic-xenial-mitaka +++ b/tests/gate-basic-xenial-mitaka @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-xenial-newton b/tests/gate-basic-xenial-newton new file mode 100755 index 0000000..75c1756 --- /dev/null +++ b/tests/gate-basic-xenial-newton @@ -0,0 +1,26 @@ +#!/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 odl controller deployment on xenial-newton.""" + +from basic_deployment import ODLControllerBasicDeployment + +if __name__ == '__main__': + deployment = ODLControllerBasicDeployment(series='xenial', + openstack='cloud:xenial-newton', + source='cloud:xenial-updates/newton', + odl_version='beryllium') + deployment.run_tests() diff --git a/tests/gate-basic-yakkety-newton b/tests/gate-basic-yakkety-newton new file mode 100644 index 0000000..1d119d7 --- /dev/null +++ b/tests/gate-basic-yakkety-newton @@ -0,0 +1,24 @@ +#!/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 odl controller deployment on yakkety-newton.""" + +from basic_deployment import ODLControllerBasicDeployment + +if __name__ == '__main__': + deployment = ODLControllerBasicDeployment(series='yakkety', + odl_version='beryllium') + deployment.run_tests() diff --git a/tests/tests.yaml b/tests/tests.yaml index e3185c6..4cf93d0 100644 --- a/tests/tests.yaml +++ b/tests/tests.yaml @@ -1,6 +1,6 @@ # Bootstrap the model if necessary. bootstrap: True -# Re-use bootstrap node instead of destroying/re-bootstrapping. +# Re-use bootstrap node. reset: True # Use tox/requirements to drive the venv instead of bundletester's venv feature. virtualenv: False