Refactors utils.load_cached_file
* adds a boolean return representing whether file was reloaded * ensures file is actually closed by using a context manager Change-Id: I4d998c34caa6dde65aaf780c188778477b7f6753
This commit is contained in:
parent
5b866f3ad1
commit
c27e1ccd3f
|
@ -345,20 +345,32 @@ class GenericUtilsTestCase(test.TestCase):
|
|||
def test_read_modified_cached_file(self):
|
||||
self.mox.StubOutWithMock(os.path, "getmtime")
|
||||
self.mox.StubOutWithMock(__builtin__, 'open')
|
||||
|
||||
os.path.getmtime(mox.IgnoreArg()).AndReturn(2)
|
||||
|
||||
fake_contents = "lorem ipsum"
|
||||
fake_file = self.mox.CreateMockAnything()
|
||||
fake_file.read().AndReturn(fake_contents)
|
||||
__builtin__.open(mox.IgnoreArg()).AndReturn(fake_file)
|
||||
fake_context_manager = self.mox.CreateMockAnything()
|
||||
fake_context_manager.__enter__().AndReturn(fake_file)
|
||||
fake_context_manager.__exit__(mox.IgnoreArg(),
|
||||
mox.IgnoreArg(),
|
||||
mox.IgnoreArg())
|
||||
|
||||
__builtin__.open(mox.IgnoreArg()).AndReturn(fake_context_manager)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
cache_data = {"data": 1123, "mtime": 1}
|
||||
data = utils.read_cached_file("/this/is/a/fake", cache_data)
|
||||
self.mox.VerifyAll()
|
||||
self.reload_called = False
|
||||
|
||||
def test_reload(reloaded_data):
|
||||
self.assertEqual(reloaded_data, fake_contents)
|
||||
self.reload_called = True
|
||||
|
||||
data = utils.read_cached_file("/this/is/a/fake", cache_data,
|
||||
reload_func=test_reload)
|
||||
self.mox.UnsetStubs()
|
||||
self.assertEqual(data, fake_contents)
|
||||
self.assertTrue(self.reload_called)
|
||||
|
||||
def test_generate_password(self):
|
||||
password = utils.generate_password()
|
||||
|
|
|
@ -1176,18 +1176,24 @@ def sanitize_hostname(hostname):
|
|||
return hostname
|
||||
|
||||
|
||||
def read_cached_file(filename, cache_info):
|
||||
"""Return the contents of a file. If the file hasn't changed since the
|
||||
last invocation, a cached version will be returned.
|
||||
def read_cached_file(filename, cache_info, reload_func=None):
|
||||
"""Read from a file if it has been modified.
|
||||
|
||||
:param cache_info: dictionary to hold opaque cache.
|
||||
:param reload_func: optional function to be called with data when
|
||||
file is reloaded due to a modification.
|
||||
|
||||
:returns: data from file
|
||||
|
||||
"""
|
||||
mtime = os.path.getmtime(filename)
|
||||
if cache_info and mtime == cache_info.get('mtime', None):
|
||||
return cache_info['data']
|
||||
|
||||
data = open(filename).read()
|
||||
cache_info['data'] = data
|
||||
cache_info['mtime'] = mtime
|
||||
return data
|
||||
if not cache_info or mtime != cache_info.get('mtime'):
|
||||
with open(filename) as fap:
|
||||
cache_info['data'] = fap.read()
|
||||
cache_info['mtime'] = mtime
|
||||
if reload_func:
|
||||
reload_func(cache_info['data'])
|
||||
return cache_info['data']
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
Loading…
Reference in New Issue