util/fscache: add trace hooks
Add trace-hooks to the FsCache._atomic_open() helper, including a primitive trace-infrastructure. They allow interrupting cache operation and running arbitrary code. The trace-hooks will be used by the test-suite to trigger the races we want to protect against. During runtime, the traces should not be used and thus will always be `None`. This is a very primitive way to hook into the runtime execution and test the atomicity of the operations. However, it is simple enough for our tests and avoids pulling in huge tracing suites. Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
This commit is contained in:
parent
290efe50fe
commit
51d0f60843
1 changed files with 24 additions and 0 deletions
|
|
@ -211,6 +211,7 @@ class FsCache(contextlib.AbstractContextManager, os.PathLike):
|
|||
|
||||
# constant properties
|
||||
_appid: str
|
||||
_tracers: Dict[str, Any]
|
||||
_path_cache: Any
|
||||
|
||||
# context-manager properties
|
||||
|
|
@ -240,6 +241,7 @@ class FsCache(contextlib.AbstractContextManager, os.PathLike):
|
|||
"""
|
||||
|
||||
self._appid = appid
|
||||
self._tracers = {}
|
||||
self._path_cache = os.fspath(path_cache)
|
||||
|
||||
self._active = False
|
||||
|
|
@ -248,6 +250,26 @@ class FsCache(contextlib.AbstractContextManager, os.PathLike):
|
|||
self._info = FsCacheInfo()
|
||||
self._info_maximum_size = 0
|
||||
|
||||
def _trace(self, trace: str):
|
||||
"""Trace execution
|
||||
|
||||
Execute registered trace-hooks for the given trace string. This allows
|
||||
tests to register callbacks that are executed at runtime at a specific
|
||||
location in the code. During normal operation, no such hooks should be
|
||||
used.
|
||||
|
||||
The trace-hooks are used to trigger race-conditions during tests and
|
||||
verify they are handled gracefully.
|
||||
|
||||
Parameters:
|
||||
-----------
|
||||
trace
|
||||
The trace-hook to run.
|
||||
"""
|
||||
|
||||
if trace in self._tracers:
|
||||
self._tracers[trace]()
|
||||
|
||||
@staticmethod
|
||||
def _calculate_size(path_target: str) -> int:
|
||||
"""Calculate total size of a directory tree
|
||||
|
|
@ -347,7 +369,9 @@ class FsCache(contextlib.AbstractContextManager, os.PathLike):
|
|||
if write:
|
||||
flags = flags | os.O_RDWR
|
||||
lock = linux.fcntl.F_WRLCK
|
||||
self._trace("_atomic_open:open")
|
||||
fd = os.open(path, flags, 0o644)
|
||||
self._trace("_atomic_open:lock")
|
||||
linux.fcntl_flock(fd, lock, wait=wait)
|
||||
|
||||
# The file might have been replaced between opening it and
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue