
* Needed to add a swift_manager/manager.py file which uses the payload software python modules to perform certain functions on behalf of the charm. These were part of the main charm, which couldn't be retained in the charm due to the charm changing to Py3. * Changed to absolute imports using the charm root as the root for all charm modules. * The py2 target in tox.ini is used to test the swift_manager/manager.py file only. * The .testr.conf file has been migrated to .stestr.conf Change-Id: If37a393aa6ed27651b04810aa0bbf69eda37d7b4
121 lines
3.8 KiB
Python
121 lines
3.8 KiB
Python
import mock
|
|
import unittest
|
|
|
|
import manager
|
|
|
|
|
|
def create_mock_load_builder_fn(mock_rings):
|
|
"""To avoid the need for swift.common.ring library, mock a basic rings
|
|
dictionary, keyed by path. Each ring has enough logic to hold a dictionary
|
|
with a single 'devs' key, which stores the list of passed dev(s) by
|
|
add_dev().
|
|
|
|
If swift (actual) ring representation diverges (see _load_builder),
|
|
this mock will need to be adapted.
|
|
|
|
:param mock_rings: a dict containing the dict form of the rings
|
|
"""
|
|
def mock_load_builder_fn(path):
|
|
class mock_ring(object):
|
|
def __init__(self, path):
|
|
self.path = path
|
|
|
|
def to_dict(self):
|
|
return mock_rings[self.path]
|
|
|
|
def add_dev(self, dev):
|
|
mock_rings[self.path]['devs'].append(dev)
|
|
|
|
return mock_ring(path)
|
|
return mock_load_builder_fn
|
|
|
|
|
|
MOCK_SWIFT_RINGS = {
|
|
'account': 'account.builder',
|
|
'container': 'container.builder',
|
|
'object': 'object.builder'
|
|
}
|
|
|
|
|
|
class TestSwiftManager(unittest.TestCase):
|
|
|
|
@mock.patch('os.path.isfile')
|
|
@mock.patch.object(manager, '_load_builder')
|
|
def test_has_minimum_zones(self, mock_load_builder, mock_is_file):
|
|
mock_rings = {}
|
|
|
|
mock_load_builder.side_effect = create_mock_load_builder_fn(mock_rings)
|
|
for ring in MOCK_SWIFT_RINGS:
|
|
mock_rings[ring] = {
|
|
'replicas': 3,
|
|
'devs': [{'zone': 1}, {'zone': 2}, None, {'zone': 3}],
|
|
}
|
|
ret = manager.has_minimum_zones(MOCK_SWIFT_RINGS)
|
|
self.assertTrue(ret['result'])
|
|
|
|
# Increase the replicas to make sure that it returns false
|
|
for ring in MOCK_SWIFT_RINGS:
|
|
mock_rings[ring]['replicas'] = 4
|
|
|
|
ret = manager.has_minimum_zones(MOCK_SWIFT_RINGS)
|
|
self.assertFalse(ret['result'])
|
|
|
|
@mock.patch.object(manager, '_load_builder')
|
|
def test_exists_in_ring(self, mock_load_builder):
|
|
mock_rings = {}
|
|
|
|
mock_load_builder.side_effect = create_mock_load_builder_fn(mock_rings)
|
|
ring = 'account'
|
|
mock_rings[ring] = {
|
|
'devs': [
|
|
{'replication_port': 6000, 'zone': 1, 'weight': 100.0,
|
|
'ip': '172.16.0.2', 'region': 1, 'port': 6000,
|
|
'replication_ip': '172.16.0.2', 'parts': 2, 'meta': '',
|
|
'device': u'bcache10', 'parts_wanted': 0, 'id': 199},
|
|
None, # Ring can have holes, so add None to simulate
|
|
{'replication_port': 6000, 'zone': 1, 'weight': 100.0,
|
|
'ip': '172.16.0.2', 'region': 1, 'id': 198,
|
|
'replication_ip': '172.16.0.2', 'parts': 2, 'meta': '',
|
|
'device': u'bcache13', 'parts_wanted': 0, 'port': 6000},
|
|
]
|
|
}
|
|
|
|
node = {
|
|
'ip': '172.16.0.2',
|
|
'region': 1,
|
|
'account_port': 6000,
|
|
'zone': 1,
|
|
'replication_port': 6000,
|
|
'weight': 100.0,
|
|
'device': u'bcache10',
|
|
}
|
|
|
|
ret = manager.exists_in_ring(ring, node)
|
|
self.assertTrue(ret)
|
|
|
|
node['region'] = 2
|
|
ret = manager.exists_in_ring(ring, node)
|
|
self.assertFalse(ret)
|
|
|
|
@mock.patch.object(manager, '_write_ring')
|
|
@mock.patch.object(manager, '_load_builder')
|
|
def test_add_dev(self, mock_load_builder, mock_write_ring):
|
|
mock_rings = {}
|
|
mock_load_builder.side_effect = create_mock_load_builder_fn(mock_rings)
|
|
ring = 'account'
|
|
mock_rings[ring] = {
|
|
'devs': []
|
|
}
|
|
|
|
new_dev = {
|
|
'meta': '',
|
|
'zone': 1,
|
|
'ip': '172.16.0.2',
|
|
'device': '/dev/sdb',
|
|
'port': 6000,
|
|
'weight': 100
|
|
}
|
|
manager.add_dev(ring, new_dev)
|
|
mock_write_ring.assert_called_once()
|
|
self.assertTrue('id' not in mock_rings[ring]['devs'][0])
|