Make the charm Python3 compliant

These changes enable the charm code to work under Python2 and Python3.  All
reactive charms should be Python3 compliant.
This commit is contained in:
Alex Kavanagh 2016-05-24 09:08:43 +00:00
parent e7d8e915ff
commit 71f1af340f
7 changed files with 53 additions and 33 deletions

View File

@ -4,12 +4,12 @@ LAYER_PATH := layers
clean:
rm -Rf build .tox .testrepository
generate: clean
LAYER_PATH=$(LAYER_PATH) tox -e generate
build: clean
LAYER_PATH=$(LAYER_PATH) tox -e build
lint:
@tox -e lint
test:
@echo Starting unit tests...
@tox -e py27
@tox -e py27,py34,py35

View File

@ -63,7 +63,7 @@ def render_configs(interfaces_list):
"""Using a list of interfaces, render the configs and, if they have
changes, restart the services on the unit.
"""
BarbicanCharm.singleton.render_interfaces(interfaces_list)
BarbicanCharm.singleton.render_with_interfaces(interfaces_list)
###
@ -112,8 +112,7 @@ class BarbicanCharm(charms_openstack.charm.OpenStackCharm):
functionality to manage a barbican unit.
"""
# don't set releases here (as we need to self refer - see below)
first_release = 'liberty'
release = 'liberty'
name = 'barbican'
packages = PACKAGES
api_ports = {
@ -123,7 +122,7 @@ class BarbicanCharm(charms_openstack.charm.OpenStackCharm):
os_ip.INTERNAL: 9313,
}
}
service_type = 'secretstore'
service_type = 'barbican'
default_service = 'barbican-api'
services = ['barbican-api', 'barbican-worker']
@ -154,11 +153,3 @@ class BarbicanCharm(charms_openstack.charm.OpenStackCharm):
self.configure_source()
# and do the actual install
super(BarbicanCharm, self).install()
# Set Barbican releases here because we need it to refer to itself. For derived
# classes of BarbicanCharm for different series we would still set the releases
# here.
BarbicanCharm.releases = {
'liberty': BarbicanCharm,
}

View File

@ -5,7 +5,7 @@ description: |
Barbican is a REST API designed for the secure storage, provisioning and
management of secrets such as passwords and encryption keys. It is aimed at
being useful for all environments, including large ephemeral Clouds
categories:
tags:
- openstack
subordinate: false
provides:

View File

@ -1,7 +1,6 @@
flake8>=2.2.4,<=2.4.1
os-testr>=0.4.1
charm-tools>=2.0.0
charms.reactive
mock>=1.2
coverage>=3.6
https://github.com/ajkavanagh/charm.openstack/zipball/master
git+https://github.com/ajkavanagh/charm.openstack#egg=charms-openstack

13
tox.ini
View File

@ -1,6 +1,7 @@
[tox]
skipsdist = True
envlist = generate
skip_missing_interpreters = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
@ -15,7 +16,7 @@ install_command =
deps =
-r{toxinidir}/requirements.txt
[testenv:generate]
[testenv:build]
basepython = python2.7
commands =
charm build --log-level DEBUG -o {toxinidir}/build src
@ -25,6 +26,16 @@ basepython = python2.7
deps = -r{toxinidir}/test-requirements.txt
commands = ostestr {posargs}
[testenv:py34]
basepython = python3.4
deps = -r{toxinidir}/test-requirements.txt
commands = ostestr {posargs}
[testenv:py35]
basepython = python3.5
deps = -r{toxinidir}/test-requirements.txt
commands = ostestr {posargs}
[testenv:lint]
basepython = python2.7
deps = -r{toxinidir}/test-requirements.txt

View File

@ -40,7 +40,13 @@ class TestBarbicanHandlers(unittest.TestCase):
mock_hook_factory(_when_not_args))
cls._patched_when_not_started = cls._patched_when_not.start()
# force requires to rerun the mock_hook decorator:
# try except is Python2/Python3 compatibility as Python3 has moved
# reload to importlib.
try:
reload(handlers)
except NameError:
import importlib
importlib.reload(handlers)
@classmethod
def tearDownClass(cls):
@ -51,7 +57,11 @@ class TestBarbicanHandlers(unittest.TestCase):
cls._patched_when_not_started = None
cls._patched_when_not = None
# and fix any breakage we did to the module
try:
reload(handlers)
except NameError:
import importlib
importlib.reload(handlers)
def setUp(self):
self._patches = {}

View File

@ -21,8 +21,8 @@ class Helper(unittest.TestCase):
self._patches = None
self._patches_start = None
def patch(self, obj, attr, return_value=None):
mocked = mock.patch.object(obj, attr)
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
@ -33,9 +33,9 @@ class Helper(unittest.TestCase):
class TestOpenStackBarbican(Helper):
def test_install(self):
self.patch(barbican.BarbicanCharm, 'singleton')
self.patch(barbican.BarbicanCharm.singleton, 'install')
barbican.install()
self.singleton.install.assert_called_once_with()
self.install.assert_called_once_with()
def test_setup_amqp_req(self):
amqp = mock.MagicMock()
@ -63,21 +63,30 @@ class TestOpenStackBarbican(Helper):
'db1', 'dbuser1', 'private_ip')
def test_setup_endpoint(self):
self.patch(barbican.BarbicanCharm, 'singleton')
self.singleton.service_type = 'type1'
self.singleton.region = 'region1'
self.singleton.public_url = 'public_url'
self.singleton.internal_url = 'internal_url'
self.singleton.admin_url = 'admin_url'
self.patch(barbican.BarbicanCharm, 'service_type',
new_callable=mock.PropertyMock)
self.patch(barbican.BarbicanCharm, 'region',
new_callable=mock.PropertyMock)
self.patch(barbican.BarbicanCharm, 'public_url',
new_callable=mock.PropertyMock)
self.patch(barbican.BarbicanCharm, 'internal_url',
new_callable=mock.PropertyMock)
self.patch(barbican.BarbicanCharm, 'admin_url',
new_callable=mock.PropertyMock)
self.service_type.return_value = 'type1'
self.region.return_value = 'region1'
self.public_url.return_value = 'public_url'
self.internal_url.return_value = 'internal_url'
self.admin_url.return_value = 'admin_url'
keystone = mock.MagicMock()
barbican.setup_endpoint(keystone)
keystone.register_endpoints.assert_called_once_with(
'type1', 'region1', 'public_url', 'internal_url', 'admin_url')
def test_render_configs(self):
self.patch(barbican.BarbicanCharm, 'singleton')
self.patch(barbican.BarbicanCharm.singleton, 'render_with_interfaces')
barbican.render_configs('interfaces-list')
self.singleton.render_interfaces.assert_called_once_with(
self.render_with_interfaces.assert_called_once_with(
'interfaces-list')