view tests/fakedirstatewritetime.py @ 33613:3b77d4787c18 stable

tests: avoid unexpected result at invocation of *.py file on Windows Invocation of "diff tool.py" in test-extdiff.t tests whether shellquote() is applied on specified command as expected. But direct invocation of "*.py" file might cause unexpected result on Windows according to suffix binding. For example, starting IDE, showing dialog to choose program to be used, and so on. In such case, running test-extdiff.t is easily timed out. This patch uses intermediate *.bat file on Windows, to avoid such unexpected result. Naming that intermediate file as "diff tool.bat" is enough to test applying shellquote().
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Tue, 01 Aug 2017 01:27:32 +0900
parents 6d73b7ff8f92
children 28b7034a916a
line wrap: on
line source

# extension to emulate invoking 'dirstate.write()' at the time
# specified by '[fakedirstatewritetime] fakenow', only when
# 'dirstate.write()' is invoked via functions below:
#
#   - 'workingctx._poststatusfixup()' (= 'repo.status()')
#   - 'committablectx.markcommitted()'

from __future__ import absolute_import

from mercurial import (
    context,
    dirstate,
    extensions,
    policy,
    util,
)

parsers = policy.importmod(r'parsers')

def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
    # execute what original parsers.pack_dirstate should do actually
    # for consistency
    actualnow = int(now)
    for f, e in dmap.iteritems():
        if e[0] == 'n' and e[3] == actualnow:
            e = parsers.dirstatetuple(e[0], e[1], e[2], -1)
            dmap[f] = e

    return orig(dmap, copymap, pl, fakenow)

def fakewrite(ui, func):
    # fake "now" of 'pack_dirstate' only if it is invoked while 'func'

    fakenow = ui.config('fakedirstatewritetime', 'fakenow')
    if not fakenow:
        # Execute original one, if fakenow isn't configured. This is
        # useful to prevent subrepos from executing replaced one,
        # because replacing 'parsers.pack_dirstate' is also effective
        # in subrepos.
        return func()

    # parsing 'fakenow' in YYYYmmddHHMM format makes comparison between
    # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
    fakenow = util.parsedate(fakenow, ['%Y%m%d%H%M'])[0]

    orig_pack_dirstate = parsers.pack_dirstate
    orig_dirstate_getfsnow = dirstate._getfsnow
    wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)

    parsers.pack_dirstate = wrapper
    dirstate._getfsnow = lambda *args: fakenow
    try:
        return func()
    finally:
        parsers.pack_dirstate = orig_pack_dirstate
        dirstate._getfsnow = orig_dirstate_getfsnow

def _poststatusfixup(orig, workingctx, status, fixup):
    ui = workingctx.repo().ui
    return fakewrite(ui, lambda : orig(workingctx, status, fixup))

def markcommitted(orig, committablectx, node):
    ui = committablectx.repo().ui
    return fakewrite(ui, lambda : orig(committablectx, node))

def extsetup(ui):
    extensions.wrapfunction(context.workingctx, '_poststatusfixup',
                            _poststatusfixup)
    extensions.wrapfunction(context.committablectx, 'markcommitted',
                            markcommitted)