Mercurial > hg
changeset 17669:405b5f8fdad7
lock-checker: new contrib extension based on work done by Mads
This makes it possible to do lock validation as part of a normal test
run. I didn't attempt any wlock validation because that's a bit more
subtle to detect properly. Thanks to the initial patch from Mads for
the idea.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Wed, 01 Aug 2012 22:13:27 -0500 |
parents | 28c43957f8b4 |
children | 9dbd5fa6d301 |
files | contrib/lock-checker.py |
diffstat | 1 files changed, 48 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/lock-checker.py Wed Aug 01 22:13:27 2012 -0500 @@ -0,0 +1,48 @@ +"""Extension to verify locks are obtained in the required places. + +This works by wrapping functions that should be surrounded by a lock +and asserting the lock is held. Missing locks are called out with a +traceback printed to stderr. + +This currently only checks store locks, not working copy locks. +""" +import os +import traceback + +def _warnstack(ui, msg, skip=1): + '''issue warning with the message and the current stack, skipping the + skip last entries''' + ui.warn('%s at:\n' % msg) + entries = traceback.extract_stack()[:-skip] + fnmax = max(len(entry[0]) for entry in entries) + for fn, ln, func, _text in entries: + ui.warn(' %*s:%-4s in %s\n' % (fnmax, fn, ln, func)) + +def _checklock(repo): + l = repo._lockref and repo._lockref() + if l is None or not l.held: + _warnstack(repo.ui, 'missing lock', skip=2) + +def reposetup(ui, repo): + orig = repo.__class__ + class lockcheckrepo(repo.__class__): + def _writejournal(self, *args, **kwargs): + _checklock(self) + return orig._writejournal(self, *args, **kwargs) + + def transaction(self, *args, **kwargs): + _checklock(self) + return orig.transaction(self, *args, **kwargs) + + # TODO(durin42): kiilerix had a commented-out lock check in + # writebranchcache and _writerequirements + + def _tag(self, *args, **kwargs): + _checklock(self) + return orig._tag(self, *args, **kwargs) + + def write(self, *args, **kwargs): + assert os.path.lexists(self._join('.hg/wlock')) + return orig.write(self, *args, **kwargs) + + repo.__class__ = lockcheckrepo