Fix generate_asn mask and add unit tests
Change-Id: I18776f026ba288a150e783e4102006e690572d6f
This commit is contained in:
parent
1ff8ee74a1
commit
3eca0062fd
3
.stestr.conf
Normal file
3
.stestr.conf
Normal file
@ -0,0 +1,3 @@
|
||||
[DEFAULT]
|
||||
test_path=./unit_tests
|
||||
top_dir=./
|
@ -2,3 +2,8 @@ name: bgp
|
||||
summary: BGP interface
|
||||
version: 1
|
||||
repo: https://github.com/openstack-charmers/charm-interface-bgp.git
|
||||
ignore:
|
||||
- 'unit_tests'
|
||||
- '.stestr.conf'
|
||||
- 'test-requirements.txt'
|
||||
- 'tox.ini'
|
||||
|
@ -45,16 +45,13 @@ class BGPEndpoint(reactive.Endpoint):
|
||||
4 200 000 000 - 4 211 081 214
|
||||
"""
|
||||
asn_base = 4211081215
|
||||
mask = netaddr.IPAddress('5.255.255.255')
|
||||
mask = netaddr.IPAddress('4.255.255.255')
|
||||
unit_ip = netaddr.IPAddress(
|
||||
ch_core.hookenv.unit_get('private-address'))
|
||||
masked_ip = unit_ip & mask
|
||||
|
||||
asn = asn_base + int(masked_ip)
|
||||
|
||||
# XXX: This assert should be removed from code and put in a unit test
|
||||
assert asn <= 4294967294
|
||||
|
||||
return asn
|
||||
|
||||
def publish_info(self, asn=None, passive=False, bindings=None):
|
||||
|
6
test-requirements.txt
Normal file
6
test-requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# Lint and unit test requirements
|
||||
flake8
|
||||
os-testr>=0.4.1
|
||||
charms.reactive
|
||||
mock>=1.2
|
||||
coverage>=3.6
|
23
tox.ini
Normal file
23
tox.ini
Normal file
@ -0,0 +1,23 @@
|
||||
[tox]
|
||||
skipsdist = True
|
||||
envlist = pep8,py35
|
||||
|
||||
[testenv]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
PYTHONHASHSEED=0
|
||||
TERM=linux
|
||||
install_command =
|
||||
pip install {opts} {packages}
|
||||
|
||||
[testenv:py35]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = ostestr {posargs}
|
||||
|
||||
[testenv:pep8]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = flake8 {posargs} . unit_tests
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
87
unit_tests/__init__.py
Normal file
87
unit_tests/__init__.py
Normal file
@ -0,0 +1,87 @@
|
||||
# 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 sys
|
||||
import mock
|
||||
|
||||
# mock out some charmhelpers libraries as they have apt install side effects
|
||||
apt_pkg = mock.MagicMock()
|
||||
charmhelpers = mock.MagicMock()
|
||||
sys.modules['apt_pkg'] = apt_pkg
|
||||
sys.modules['charmhelpers'] = charmhelpers
|
||||
sys.modules['charmhelpers.core'] = charmhelpers.core
|
||||
sys.modules['charmhelpers.core.decorators'] = charmhelpers.core.decorators
|
||||
sys.modules['charmhelpers.core.hookenv'] = charmhelpers.core.hookenv
|
||||
sys.modules['charmhelpers.core.host'] = charmhelpers.core.host
|
||||
sys.modules['charmhelpers.core.templating'] = charmhelpers.core.templating
|
||||
sys.modules['charmhelpers.core.unitdata'] = charmhelpers.core.unitdata
|
||||
sys.modules['charmhelpers.contrib'] = charmhelpers.contrib
|
||||
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
||||
sys.modules['charmhelpers.contrib.openstack.ha'] = (
|
||||
charmhelpers.contrib.openstack.ha)
|
||||
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
||||
charmhelpers.contrib.openstack.utils)
|
||||
sys.modules['charmhelpers.contrib.openstack.templating'] = (
|
||||
charmhelpers.contrib.openstack.templating)
|
||||
sys.modules['charmhelpers.contrib.openstack.context'] = (
|
||||
charmhelpers.contrib.openstack.context)
|
||||
sys.modules['charmhelpers.contrib.network'] = charmhelpers.contrib.network
|
||||
sys.modules['charmhelpers.contrib.network.ip'] = (
|
||||
charmhelpers.contrib.network.ip)
|
||||
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)
|
||||
|
||||
# mock in the openstack releases so that the tests can run
|
||||
# Note that these don't need to be maintained UNLESS new functionality is for
|
||||
# later OpenStack releases.
|
||||
charmhelpers.contrib.openstack.utils.OPENSTACK_RELEASES = (
|
||||
'diablo',
|
||||
'essex',
|
||||
'folsom',
|
||||
'grizzly',
|
||||
'havana',
|
||||
'icehouse',
|
||||
'juno',
|
||||
'kilo',
|
||||
'liberty',
|
||||
'mitaka',
|
||||
'newton',
|
||||
'ocata',
|
||||
'pike',
|
||||
)
|
||||
|
||||
|
||||
def _fake_retry(num_retries, base_delay=0, exc_type=Exception):
|
||||
def _retry_on_exception_inner_1(f):
|
||||
def _retry_on_exception_inner_2(*args, **kwargs):
|
||||
return f(*args, **kwargs)
|
||||
return _retry_on_exception_inner_2
|
||||
return _retry_on_exception_inner_1
|
||||
|
||||
|
||||
mock.patch(
|
||||
'charmhelpers.core.decorators.retry_on_exception',
|
||||
_fake_retry).start()
|
||||
|
||||
|
||||
def _fake_cached(f):
|
||||
return f
|
||||
|
||||
|
||||
mock.patch(
|
||||
'charmhelpers.core.hookenv.cached',
|
||||
_fake_cached).start()
|
32
unit_tests/test_provides.py
Normal file
32
unit_tests/test_provides.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright 2018 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 unit_tests.utils as ut_utils
|
||||
import provides
|
||||
|
||||
|
||||
class TestBGPProvides(ut_utils.BaseTestCase):
|
||||
def test_generate_asn_min(self):
|
||||
self.patch_object(provides, 'ch_core')
|
||||
self.ch_core.hookenv.unit_get.return_value = '0.0.0.0'
|
||||
endpoint = provides.BGPEndpoint('bgpserver')
|
||||
asn = endpoint.generate_asn()
|
||||
self.assertEqual(asn, 4211081215)
|
||||
|
||||
def test_generate_asn_max(self):
|
||||
self.patch_object(provides, 'ch_core')
|
||||
self.ch_core.hookenv.unit_get.return_value = '255.255.255.255'
|
||||
endpoint = provides.BGPEndpoint('bgpserver')
|
||||
asn = endpoint.generate_asn()
|
||||
self.assertEqual(asn, 4294967294)
|
82
unit_tests/utils.py
Normal file
82
unit_tests/utils.py
Normal file
@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
|
||||
# Note that the unit_tests/__init__.py also mocks out two charmhelpers imports
|
||||
# that have side effects that try to apt install modules:
|
||||
# sys.modules['charmhelpers.contrib.openstack.utils'] = mock.MagicMock()
|
||||
# sys.modules['charmhelpers.contrib.network.ip'] = mock.MagicMock()
|
||||
|
||||
import contextlib
|
||||
import io
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def patch_open():
|
||||
'''Patch open() to allow mocking both open() itself and the file that is
|
||||
yielded.
|
||||
|
||||
Yields the mock for "open" and "file", respectively.'''
|
||||
mock_open = mock.MagicMock(spec=open)
|
||||
mock_file = mock.MagicMock(spec=io.FileIO)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def stub_open(*args, **kwargs):
|
||||
mock_open(*args, **kwargs)
|
||||
yield mock_file
|
||||
|
||||
with mock.patch('builtins.open', stub_open):
|
||||
yield mock_open, mock_file
|
||||
|
||||
|
||||
class BaseTestCase(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_object(self, obj, attr, return_value=None, name=None, new=None,
|
||||
**kwargs):
|
||||
if name is None:
|
||||
name = attr
|
||||
if new is not None:
|
||||
mocked = mock.patch.object(obj, attr, new=new, **kwargs)
|
||||
else:
|
||||
mocked = mock.patch.object(obj, attr, **kwargs)
|
||||
self._patches[name] = mocked
|
||||
started = mocked.start()
|
||||
if new is None:
|
||||
started.return_value = return_value
|
||||
self._patches_start[name] = started
|
||||
setattr(self, name, started)
|
||||
|
||||
def patch(self, item, return_value=None, name=None, new=None, **kwargs):
|
||||
if name is None:
|
||||
raise RuntimeError("Must pass 'name' to .patch()")
|
||||
if new is not None:
|
||||
mocked = mock.patch(item, new=new, **kwargs)
|
||||
else:
|
||||
mocked = mock.patch(item, **kwargs)
|
||||
self._patches[name] = mocked
|
||||
started = mocked.start()
|
||||
if new is None:
|
||||
started.return_value = return_value
|
||||
self._patches_start[name] = started
|
||||
setattr(self, name, started)
|
Loading…
Reference in New Issue
Block a user