Clean up how PatchPolicies works

We've got these lovely __enter__ and __exit__ methods; let's use them!

Note that this also changes how we patch classes' setUp methods so we
don't set self._orig_POLICIES when the class is already patched.  I
hope this may fix some sporadic failures that include tracebacks
that look like

  proxy ERROR: ERROR 500 Traceback (most recent call last):
    File ".../swift/obj/server.py", line 1105, in __call__
      res = getattr(self, req.method)(req)
    File ".../swift/common/utils.py", line 1626, in _timing_stats
      resp = func(ctrl, *args, **kwargs)
    File ".../swift/obj/server.py", line 880, in GET
      policy=policy, frag_prefs=frag_prefs)
    File ".../swift/obj/server.py", line 211, in get_diskfile
      return self._diskfile_router[policy].get_diskfile(
    File ".../swift/obj/diskfile.py", line 555, in __getitem__
      return self.policy_to_manager[policy]
  KeyError: ECStoragePolicy(...)

... and try to unpatch more gracefully with TestCase.addCleanup

Change-Id: Iaa3d42ec21758b0707155878a645e665aa36696c
This commit is contained in:
Tim Burke
2017-04-26 17:13:37 -07:00
parent 408500320b
commit 1b991803e8

View File

@@ -121,7 +121,7 @@ def patch_policies(thing_or_policies=None, legacy_only=False,
class PatchPolicies(object):
"""
Why not mock.patch? In my case, when used as a decorator on the class it
seemed to patch setUp at the wrong time (i.e. in setup the global wasn't
seemed to patch setUp at the wrong time (i.e. in setUp the global wasn't
patched yet)
"""
@@ -168,42 +168,38 @@ class PatchPolicies(object):
"""
orig_setUp = cls.setUp
orig_tearDown = cls.tearDown
def unpatch_cleanup(cls_self):
if cls_self._policies_patched:
self.__exit__()
cls_self._policies_patched = False
def setUp(cls_self):
self._orig_POLICIES = storage_policy._POLICIES
if not getattr(cls_self, '_policies_patched', False):
storage_policy._POLICIES = self.policies
self._setup_rings()
self.__enter__()
cls_self._policies_patched = True
cls_self.addCleanup(unpatch_cleanup, cls_self)
orig_setUp(cls_self)
def tearDown(cls_self):
orig_tearDown(cls_self)
storage_policy._POLICIES = self._orig_POLICIES
cls.setUp = setUp
cls.tearDown = tearDown
return cls
def _patch_method(self, f):
@functools.wraps(f)
def mywrapper(*args, **kwargs):
self._orig_POLICIES = storage_policy._POLICIES
try:
storage_policy._POLICIES = self.policies
self._setup_rings()
with self:
return f(*args, **kwargs)
finally:
storage_policy._POLICIES = self._orig_POLICIES
return mywrapper
def __enter__(self):
self._orig_POLICIES = storage_policy._POLICIES
storage_policy._POLICIES = self.policies
self._setup_rings()
try:
self._setup_rings()
except: # noqa
self.__exit__()
raise
def __exit__(self, *args):
storage_policy._POLICIES = self._orig_POLICIES