From 3a7f1ffb959e185b67f0a797171eb7bdfe458bb4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 2 Oct 2015 10:24:54 +0200 Subject: [PATCH] Port scheduler host manager to Python 3 * Rewrite ReadOnlyDict using collections.Mapping: collections.Mapping has no method to modify the dictionary and is available on Python 2 and Python 3. Add also a __repr__() method to ease debug. Remove ReadOnlyDict.update() method: a read-only dictionary must not be modifiable. * test_host_manager.py: sort dictionaries using a key function to have a reliable order for the list of dictionaries. On Python 3, the hash function is now randomized. * tox.ini. add cinder/tests/unit/scheduler/ tests to Python 3.4 Blueprint cinder-python3 Change-Id: I34d98d6a75fef907251719f0d46b025d8e8b2b65 --- cinder/scheduler/host_manager.py | 39 +++++++------------ .../tests/unit/scheduler/test_host_manager.py | 7 +++- tox.ini | 11 ++++++ 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/cinder/scheduler/host_manager.py b/cinder/scheduler/host_manager.py index 45077e5e9..9cf70739b 100644 --- a/cinder/scheduler/host_manager.py +++ b/cinder/scheduler/host_manager.py @@ -17,7 +17,7 @@ Manage hosts in the current zone. """ -import UserDict +import collections from oslo_config import cfg from oslo_log import log as logging @@ -57,36 +57,25 @@ CONF.import_opt('max_over_subscription_ratio', 'cinder.volume.driver') LOG = logging.getLogger(__name__) -class ReadOnlyDict(UserDict.IterableUserDict): +class ReadOnlyDict(collections.Mapping): """A read-only dict.""" def __init__(self, source=None): - self.data = {} - self.update(source) - - def __setitem__(self, key, item): - raise TypeError - - def __delitem__(self, key): - raise TypeError + if source is not None: + self.data = dict(source) + else: + self.data = {} - def clear(self): - raise TypeError + def __getitem__(self, key): + return self.data[key] - def pop(self, key, *args): - raise TypeError + def __iter__(self): + return iter(self.data) - def popitem(self): - raise TypeError + def __len__(self): + return len(self.data) - def update(self, source=None): - if source is None: - return - elif isinstance(source, UserDict.UserDict): - self.data = source.data - elif isinstance(source, type({})): - self.data = source - else: - raise TypeError + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, self.data) class HostState(object): diff --git a/cinder/tests/unit/scheduler/test_host_manager.py b/cinder/tests/unit/scheduler/test_host_manager.py index 2f27aced0..6d89f7ee2 100644 --- a/cinder/tests/unit/scheduler/test_host_manager.py +++ b/cinder/tests/unit/scheduler/test_host_manager.py @@ -389,8 +389,13 @@ class HostManagerTestCase(test.TestCase): 'provisioned_capacity_gb': 9300}, } ] + + def sort_func(data): + return data['name'] + self.assertEqual(len(expected), len(res)) - self.assertEqual(sorted(expected), sorted(res)) + self.assertEqual(sorted(expected, key=sort_func), + sorted(res, key=sort_func)) class HostStateTestCase(test.TestCase): diff --git a/tox.ini b/tox.ini index 720d14492..378af8501 100644 --- a/tox.ini +++ b/tox.ini @@ -31,6 +31,17 @@ commands = python -m testtools.run \ cinder.tests.unit.image.test_glance \ cinder.tests.unit.keymgr.test_mock_key_mgr \ + cinder.tests.unit.scheduler.test_allocated_capacity_weigher \ + cinder.tests.unit.scheduler.test_capacity_weigher \ + cinder.tests.unit.scheduler.test_chance_weigher \ + cinder.tests.unit.scheduler.test_filter_scheduler \ + cinder.tests.unit.scheduler.test_goodness_weigher \ + cinder.tests.unit.scheduler.test_host_filters \ + cinder.tests.unit.scheduler.test_host_manager \ + cinder.tests.unit.scheduler.test_rpcapi \ + cinder.tests.unit.scheduler.test_scheduler \ + cinder.tests.unit.scheduler.test_scheduler_options \ + cinder.tests.unit.scheduler.test_volume_number_weigher \ cinder.tests.unit.targets.test_base_iscsi_driver \ cinder.tests.unit.targets.test_cxt_driver \ cinder.tests.unit.targets.test_iser_driver \ -- 2.45.2