summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorviswesn <viswesn@gmail.com>2016-11-12 12:36:18 +0530
committerviswesn <viswesn@gmail.com>2016-11-12 12:36:18 +0530
commit61e025b863a8d9c2abbb1a760640bac065d1b451 (patch)
treee42f6ed64c2c2f266304832ee6a35f63094e356f
parent6dc5c7028e32d7055ed532cf1e47963fa1a46dec (diff)
downloadcharm-murano-61e025b863a8d9c2abbb1a760640bac065d1b451.zip
charm-murano-61e025b863a8d9c2abbb1a760640bac065d1b451.tar.gz
charm-murano-61e025b863a8d9c2abbb1a760640bac065d1b451.tar.bz2
Updated unit and amulet testing for Murano charm
-rw-r--r--src/tests/basic_deployment.py358
-rwxr-xr-xsrc/tests/gate-basic-trusty-icehouse23
-rwxr-xr-xsrc/tests/gate-basic-trusty-liberty25
-rwxr-xr-xsrc/tests/gate-basic-trusty-mitaka25
-rwxr-xr-xsrc/tests/gate-basic-xenial-mitaka8
-rw-r--r--test-requirements.txt2
-rw-r--r--unit_tests/__init__.py2
-rw-r--r--unit_tests/test_lib_charm_openstack_openvswitch_odl.py47
-rw-r--r--unit_tests/test_openvswitch_odl_handlers.py43
9 files changed, 278 insertions, 255 deletions
diff --git a/src/tests/basic_deployment.py b/src/tests/basic_deployment.py
index 4e3d967..14c87eb 100644
--- a/src/tests/basic_deployment.py
+++ b/src/tests/basic_deployment.py
@@ -1,113 +1,88 @@
-# 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 subprocess
import amulet
import json
-import subprocess
import time
+import muranoclient.client as murano_client
+from keystoneclient import session as keystone_session
+from keystoneclient.auth import identity as keystone_identity
-import charmhelpers.contrib.openstack.amulet.deployment as amulet_deployment
-import charmhelpers.contrib.openstack.amulet.utils as os_amulet_utils
+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 = os_amulet_utils.OpenStackAmuletUtils(os_amulet_utils.DEBUG)
+u = OpenStackAmuletUtils(DEBUG)
-class SDNCharmDeployment(amulet_deployment.OpenStackAmuletDeployment):
- """Amulet tests on a basic sdn_charm deployment."""
+class MuranoBasicDeployment(OpenStackAmuletDeployment):
+ """Amulet tests on a basic murano deployment."""
def __init__(self, series, openstack=None, source=None, stable=False):
"""Deploy the entire test environment."""
- super(SDNCharmDeployment, self).__init__(series, openstack,
- source, stable)
+ super(MuranoBasicDeployment, 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 = ['mysql', 'mongodb']
+ 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 sdn_charm is local,
+ Add the services that we're testing, where murano 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': 'sdn_charm'}
+ this_service = {'name': 'murano'}
other_services = [
- {
- 'name': 'nova-compute',
- 'constraints': {'mem': '4G'},
- },
- {
- 'name': 'neutron-api',
- },
- {
- 'name': 'neutron-gateway',
- },
- {'name': 'mysql'},
+ {'name': 'percona-cluster', 'constraints': {'mem': '3072M'}},
{'name': 'rabbitmq-server'},
{'name': 'keystone'},
- {'name': 'nova-cloud-controller'},
- {'name': 'glance'},
]
- super(SDNCharmDeployment, self)._add_services(this_service,
- other_services)
+ super(MuranoBasicDeployment, self)._add_services(this_service,
+ other_services)
def _add_relations(self):
"""Add all of the relations for the services."""
relations = {
- 'nova-compute:neutron-plugin': 'sdn_charm:neutron-plugin',
- 'keystone:shared-db': 'mysql:shared-db',
- 'nova-cloud-controller:shared-db': 'mysql:shared-db',
- 'nova-cloud-controller:amqp': 'rabbitmq-server:amqp',
- 'nova-cloud-controller:image-service': 'glance:image-service',
- 'nova-cloud-controller:identity-service':
- 'keystone:identity-service',
- 'nova-compute:cloud-compute':
- 'nova-cloud-controller:cloud-compute',
- 'nova-compute:amqp': 'rabbitmq-server:amqp',
- 'nova-compute:image-service': 'glance:image-service',
- 'glance:shared-db': 'mysql:shared-db',
- 'glance:identity-service': 'keystone:identity-service',
- 'glance:amqp': 'rabbitmq-server:amqp',
- 'neutron-api:shared-db': 'mysql:shared-db',
- 'neutron-api:amqp': 'rabbitmq-server:amqp',
- 'neutron-api:neutron-api': 'nova-cloud-controller:neutron-api',
- 'neutron-api:identity-service': 'keystone:identity-service',
- 'neutron-gateway:amqp': 'rabbitmq-server:amqp',
- 'neutron-gateway:neutron-plugin-api':
- 'neutron-api:neutron-plugin-api',
- 'neutron-gateway:quantum-network-service':
- 'nova-cloud-controller:quantum-network-service',
- 'neutron-gateway:juju-info': 'sdn_charm:container',
+ 'murano:shared-db': 'percona-cluster:shared-db',
+ 'murano:amqp': 'rabbitmq-server:amqp',
+ 'murano:identity-service': 'keystone:identity-service',
+ 'keystone:shared-db': 'percona-cluster:shared-db',
+
}
- super(SDNCharmDeployment, self)._add_relations(relations)
+ super(MuranoBasicDeployment, self)._add_relations(relations)
def _configure_services(self):
"""Configure all of the services."""
- keystone_config = {'admin-password': 'openstack',
- 'admin-token': 'ubuntutesting'}
- configs = {'keystone': keystone_config}
- super(SDNCharmDeployment, self)._configure_services(configs)
+ keystone_config = {
+ 'admin-password': 'openstack',
+ 'admin-token': 'ubuntutesting'
+ }
+ pxc_config = {
+ 'dataset-size': '25%',
+ 'max-connections': 1000,
+ 'root-password': 'ChangeMe123',
+ 'sst-password': 'ChangeMe123',
+ }
+ configs = {
+ 'keystone': keystone_config,
+ 'percona-cluster': pxc_config,
+ }
+ super(MuranoBasicDeployment, self)._configure_services(configs)
def _get_token(self):
return self.keystone.service_catalog.catalog['token']['id']
@@ -115,12 +90,14 @@ class SDNCharmDeployment(amulet_deployment.OpenStackAmuletDeployment):
def _initialize_tests(self):
"""Perform final initialization before tests get run."""
# Access the sentries for inspecting service units
- self.sdn_charm_sentry = self.d.sentry['sdn_charm'][0]
- self.mysql_sentry = self.d.sentry['mysql'][0]
+ self.murano_sentry = self.d.sentry['murano'][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]
- self.sdn_charm_svcs = [
- 'sdn_charm-agent', 'sdn_charm-api']
+ 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 endpoint
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
@@ -128,16 +105,20 @@ class SDNCharmDeployment(amulet_deployment.OpenStackAmuletDeployment):
password='openstack',
tenant='admin')
- def check_and_wait(self, check_command, interval=2, max_wait=200,
- desc=None):
- waited = 0
- while not check_command() or waited > max_wait:
- if desc:
- u.log.debug(desc)
- time.sleep(interval)
- waited = waited + interval
- if waited > max_wait:
- raise Exception('cmd failed {}'.format(check_command))
+ # Authenticate admin with murano endpoint
+ murano_ep = self.keystone.service_catalog.url_for(
+ service_type='application-catalog',
+ endpoint_type='publicURL')
+
+ keystone_ep = self.keystone.service_catalog.url_for(
+ service_type='identity',
+ endpoint_type='publicURL')
+
+ auth = keystone_identity.V2Token(auth_url=keystone_ep,
+ token=self.keystone.auth_token)
+ sess = keystone_session.Session(auth=auth)
+ self.murano = murano_client.Client(version=1, session=sess,
+ endpoint_override=murano_ep)
def _run_action(self, unit_id, action, *args):
command = ["juju", "action", "do", "--format=json", unit_id, action]
@@ -170,12 +151,217 @@ class SDNCharmDeployment(amulet_deployment.OpenStackAmuletDeployment):
service units."""
u.log.debug('Checking system services on units...')
+ murano_svcs = [
+ 'murano-api', 'murano-engine'
+ ]
+
service_names = {
- self.sdn_charm_sentry: self.sdn_charm_svcs,
+ self.murano_sentry: murano_svcs,
}
ret = u.validate_services_by_name(service_names)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
- u.log.debug('OK') \ No newline at end of file
+ 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...')
+ endpoint_check = {
+ 'adminURL': u.valid_url,
+ 'id': u.not_null,
+ 'region': 'RegionOne',
+ 'publicURL': u.valid_url,
+ 'internalURL': u.valid_url
+ }
+ expected = {
+ 'application-catalog': [endpoint_check],
+ }
+ actual = self.keystone.service_catalog.get_endpoints()
+
+ ret = u.validate_svc_catalog_endpoint_data(expected, actual)
+ if ret:
+ amulet.raise_status(amulet.FAIL, msg=ret)
+
+ u.log.debug('OK')
+
+ def test_114_murano_api_endpoint(self):
+ """Verify the murano api endpoint data."""
+ u.log.debug('Checking murano api endpoint data...')
+ endpoints = self.keystone.endpoints.list()
+ u.log.debug(endpoints)
+ admin_port = internal_port = public_port = '8082'
+ expected = {'id': u.not_null,
+ 'region': 'RegionOne',
+ 'adminurl': u.valid_url,
+ 'internalurl': u.valid_url,
+ 'publicurl': u.valid_url,
+ 'service_id': u.not_null}
+
+ ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
+ public_port, expected)
+ if ret:
+ message = 'murano endpoint: {}'.format(ret)
+ amulet.raise_status(amulet.FAIL, msg=message)
+
+ u.log.debug('OK')
+
+ def test_200_murano_identity_relation(self):
+ """Verify the murano to keystone identity-service relation data"""
+ u.log.debug('Checking murano to keystone identity-service '
+ 'relation data...')
+ unit = self.murano_sentry
+ relation = ['identity-service', 'keystone:identity-service']
+ murano_relation = unit.relation('identity-service',
+ 'keystone:identity-service')
+ murano_ip = murano_relation['private-address']
+ murano_endpoint = "http://%s:8082" % (murano_ip)
+
+ expected = {
+ 'admin_url': murano_endpoint,
+ 'internal_url': murano_endpoint,
+ 'private-address': murano_ip,
+ 'public_url': murano_endpoint,
+ 'region': 'RegionOne',
+ 'service': 'murano',
+ }
+
+ ret = u.validate_relation_data(unit, relation, expected)
+ if ret:
+ message = u.relation_error('murano identity-service', ret)
+ amulet.raise_status(amulet.FAIL, msg=message)
+
+ u.log.debug('OK')
+
+ def test_201_keystone_murano_identity_relation(self):
+ """Verify the keystone to murano identity-service relation data"""
+ u.log.debug('Checking keystone:murano identity relation data...')
+ unit = self.keystone_sentry
+ relation = ['identity-service', 'murano:identity-service']
+ id_relation = unit.relation('identity-service',
+ 'murano:identity-service')
+ id_ip = id_relation['private-address']
+ expected = {
+ 'admin_token': 'ubuntutesting',
+ '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': 'murano',
+ }
+ 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_murano_amqp_relation(self):
+ """Verify the murano to rabbitmq-server amqp relation data"""
+ u.log.debug('Checking murano:rabbitmq amqp relation data...')
+ unit = self.murano_sentry
+ relation = ['amqp', 'rabbitmq-server:amqp']
+ expected = {
+ 'username': 'murano',
+ 'private-address': u.valid_ip,
+ 'vhost': 'openstack'
+ }
+
+ ret = u.validate_relation_data(unit, relation, expected)
+ if ret:
+ message = u.relation_error('murano amqp', ret)
+ amulet.raise_status(amulet.FAIL, msg=message)
+
+ u.log.debug('OK')
+
+ def test_204_amqp_murano_relation(self):
+ """Verify the rabbitmq-server to murano amqp relation data"""
+ u.log.debug('Checking rabbitmq:murano amqp relation data...')
+ unit = self.rabbitmq_sentry
+ relation = ['amqp', 'murano: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 amqp', ret)
+ amulet.raise_status(amulet.FAIL, msg=message)
+
+ u.log.debug('OK')
+
+ 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.murano_sentry
+ juju_service = 'murano'
+
+ # 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/murano/murano.conf'
+ services = {
+ 'murano-api': conf_file,
+ 'murano-engine': 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 _test_910_pause_and_resume(self):
+ """The services can be paused and resumed. """
+ u.log.debug('Checking pause and resume actions...')
+ unit_name = "murano/0"
+ unit = self.d.sentry['murano'][0]
+ juju_service = 'murano'
+
+ assert u.status_get(unit)[0] == "active"
+
+ action_id = self._run_action(unit_name, "pause")
+ assert self._wait_on_action(action_id), "Pause action failed."
+ assert u.status_get(unit)[0] == "maintenance"
+
+ # trigger config-changed to ensure that services are still stopped
+ u.log.debug("Making config change on murano ...")
+ self.d.configure(juju_service, {'debug': 'True'})
+ assert u.status_get(unit)[0] == "maintenance"
+ self.d.configure(juju_service, {'debug': 'False'})
+ assert u.status_get(unit)[0] == "maintenance"
+
+ action_id = self._run_action(unit_name, "resume")
+ assert self._wait_on_action(action_id), "Resume action failed."
+ assert u.status_get(unit)[0] == "active"
+ u.log.debug('OK')
diff --git a/src/tests/gate-basic-trusty-icehouse b/src/tests/gate-basic-trusty-icehouse
deleted file mode 100755
index bc30915..0000000
--- a/src/tests/gate-basic-trusty-icehouse
+++ /dev/null
@@ -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 SDN Charm deployment on trusty-icehouse."""
-
-from basic_deployment import SDNCharmDeployment
-
-if __name__ == '__main__':
- deployment = SDNCharmDeployment(series='trusty')
- deployment.run_tests() \ No newline at end of file
diff --git a/src/tests/gate-basic-trusty-liberty b/src/tests/gate-basic-trusty-liberty
deleted file mode 100755
index f4fe1ff..0000000
--- a/src/tests/gate-basic-trusty-liberty
+++ /dev/null
@@ -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 SDN Charm deployment on trusty-liberty."""
-
-from basic_deployment import SDNCharmDeployment
-
-if __name__ == '__main__':
- deployment = SDNCharmDeployment(series='trusty',
- openstack='cloud:trusty-liberty',
- source='cloud:trusty-updates/liberty')
- deployment.run_tests() \ No newline at end of file
diff --git a/src/tests/gate-basic-trusty-mitaka b/src/tests/gate-basic-trusty-mitaka
deleted file mode 100755
index 9142a10..0000000
--- a/src/tests/gate-basic-trusty-mitaka
+++ /dev/null
@@ -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 SDN Charm deployment on trusty-mitaka."""
-
-from basic_deployment import SDNCharmDeployment
-
-if __name__ == '__main__':
- deployment = SDNCharmDeployment(series='trusty',
- openstack='cloud:trusty-mitaka',
- source='cloud:trusty-updates/mitaka')
- deployment.run_tests() \ No newline at end of file
diff --git a/src/tests/gate-basic-xenial-mitaka b/src/tests/gate-basic-xenial-mitaka
index 37725c2..7182977 100755
--- a/src/tests/gate-basic-xenial-mitaka
+++ b/src/tests/gate-basic-xenial-mitaka
@@ -14,10 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Amulet tests on a basic SDN Charm deployment on xenial-mitaka."""
+"""Amulet tests on a basic Murano Charm deployment on xenial-mitaka."""
-from basic_deployment import SDNCharmDeployment
+from basic_deployment import MuranoBasicDeployment
if __name__ == '__main__':
- deployment = SDNCharmDeployment(series='xenial')
- deployment.run_tests() \ No newline at end of file
+ deployment = MuranoBasicDeployment(series='xenial')
+ deployment.run_tests()
diff --git a/test-requirements.txt b/test-requirements.txt
index 4c9c8dd..368dbf2 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -4,4 +4,4 @@ os-testr>=0.4.1
charms.reactive
mock>=1.2
coverage>=3.6
-git+https://github.com/openstack/charms.openstack.git#egg=charms-openstack \ No newline at end of file
+git+https://github.com/openstack/charms.openstack.git#egg=charms-openstack
diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py
index 1ca5eb6..12469eb 100644
--- a/unit_tests/__init__.py
+++ b/unit_tests/__init__.py
@@ -43,4 +43,4 @@ sys.modules['charmhelpers.fetch'] = charmhelpers.fetch
sys.modules['charmhelpers.cli'] = charmhelpers.cli
sys.modules['charmhelpers.contrib.hahelpers'] = charmhelpers.contrib.hahelpers
sys.modules['charmhelpers.contrib.hahelpers.cluster'] = (
- charmhelpers.contrib.hahelpers.cluster) \ No newline at end of file
+ charmhelpers.contrib.hahelpers.cluster)
diff --git a/unit_tests/test_lib_charm_openstack_openvswitch_odl.py b/unit_tests/test_lib_charm_openstack_openvswitch_odl.py
deleted file mode 100644
index 7c4385b..0000000
--- a/unit_tests/test_lib_charm_openstack_openvswitch_odl.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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.
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import unittest
-
-import mock
-
-import charm.openstack.sdn_charm as sdn_charm
-
-
-class Helper(unittest.TestCase):
-
- def setUp(self):
- self._patches = {}
- self._patches_start = {}
-
- def tearDown(self):
- for k, v in self._patches.items():
- v.stop()
- setattr(self, k, None)
- self._patches = None
- self._patches_start = None
-
- def patch(self, obj, attr, return_value=None, **kwargs):
- mocked = mock.patch.object(obj, attr, **kwargs)
- self._patches[attr] = mocked
- started = mocked.start()
- started.return_value = return_value
- self._patches_start[attr] = started
- setattr(self, attr, started)
-
-
-class TestSDNCharm(Helper): \ No newline at end of file
diff --git a/unit_tests/test_openvswitch_odl_handlers.py b/unit_tests/test_openvswitch_odl_handlers.py
deleted file mode 100644
index f107ee6..0000000
--- a/unit_tests/test_openvswitch_odl_handlers.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# 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.
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import mock
-
-import reactive.sdn_charm_handlers as handlers
-
-import charms_openstack.test_utils as test_utils
-
-
-class TestRegisteredHooks(test_utils.TestRegisteredHooks):
-
- def test_hooks(self):
- defaults = [
- 'charm.installed',
- 'config.changed',
- 'update-status']
- hook_set = {
- 'when': {
- },
- 'when_not': {
- }
- }
- # test that the hooks were registered via the
- # reactive.barbican_handlers
- self.registered_hooks_test_helper(handlers, hook_set, defaults)
-
-
-class TestSDNCharmHandles(test_utils.PatchHelper): \ No newline at end of file

This mirror site include all the OpenStack related repositories under: openstack, openstack-dev and openstack-infra.

NOTE: All repositories are updated every one hour.

Usage

For Git Clone
 git clone http://git.trystack.cn/openstack/nova.git 
For DevStack

Add GIT_BASE, NOVNC_REPO and SPICE_REPO variables to local.conf file.

[[local|localrc]]

# use TryStack git mirror
GIT_BASE=http://git.trystack.cn
NOVNC_REPO=http://git.trystack.cn/kanaka/noVNC.git
SPICE_REPO=http://git.trystack.cn/git/spice/spice-html5.git