This should be useful for some shell invocation.
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- stable
- Lint
No Linters Available - Unit
No Unit Test Coverage
This should be useful for some shell invocation.
No Linters Available |
No Unit Test Coverage |
Path | Packages | |||
---|---|---|---|---|
M | tests/run-tests.py (6 lines) | |||
M | tests/test-racy-mutations.t (16 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
86e59ddfa1e1 | c8533860858f | Pierre-Yves David | Apr 6 2022, 12:50 PM |
def defineport(i): | def defineport(i): | ||||
offset = '' if i == 0 else '%s' % i | offset = '' if i == 0 else '%s' % i | ||||
env["HGPORT%s" % offset] = '%s' % (self._startport + i) | env["HGPORT%s" % offset] = '%s' % (self._startport + i) | ||||
env = os.environ.copy() | env = os.environ.copy() | ||||
env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' | env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' | ||||
env['HGEMITWARNINGS'] = '1' | env['HGEMITWARNINGS'] = '1' | ||||
env['TESTTMP'] = _bytes2sys(self._testtmp) | env['TESTTMP'] = _bytes2sys(self._testtmp) | ||||
# the FORWARD_SLASH version is useful when running `sh` on non unix | |||||
# system (e.g. Windows) | |||||
env['TESTTMP_FORWARD_SLASH'] = env['TESTTMP'].replace(os.sep, '/') | |||||
uid_file = os.path.join(_bytes2sys(self._testtmp), 'UID') | uid_file = os.path.join(_bytes2sys(self._testtmp), 'UID') | ||||
env['HGTEST_UUIDFILE'] = uid_file | env['HGTEST_UUIDFILE'] = uid_file | ||||
env['TESTNAME'] = self.name | env['TESTNAME'] = self.name | ||||
env['HOME'] = _bytes2sys(self._testtmp) | env['HOME'] = _bytes2sys(self._testtmp) | ||||
if WINDOWS: | if WINDOWS: | ||||
env['REALUSERPROFILE'] = env['USERPROFILE'] | env['REALUSERPROFILE'] = env['USERPROFILE'] | ||||
# py3.8+ ignores HOME: https://bugs.python.org/issue36264 | # py3.8+ ignores HOME: https://bugs.python.org/issue36264 | ||||
env['USERPROFILE'] = env['HOME'] | env['USERPROFILE'] = env['HOME'] | ||||
def _run(self, testdescs): | def _run(self, testdescs): | ||||
testdir = getcwdb() | testdir = getcwdb() | ||||
# assume all tests in same folder for now | # assume all tests in same folder for now | ||||
if testdescs: | if testdescs: | ||||
pathname = os.path.dirname(testdescs[0]['path']) | pathname = os.path.dirname(testdescs[0]['path']) | ||||
if pathname: | if pathname: | ||||
testdir = os.path.join(testdir, pathname) | testdir = os.path.join(testdir, pathname) | ||||
self._testdir = osenvironb[b'TESTDIR'] = testdir | self._testdir = osenvironb[b'TESTDIR'] = testdir | ||||
osenvironb[b'TESTDIR_FORWARD_SLASH'] = osenvironb[b'TESTDIR'].replace(os.sep.encode('ascii'), b'/') | |||||
if self.options.outputdir: | if self.options.outputdir: | ||||
self._outputdir = canonpath(_sys2bytes(self.options.outputdir)) | self._outputdir = canonpath(_sys2bytes(self.options.outputdir)) | ||||
else: | else: | ||||
self._outputdir = getcwdb() | self._outputdir = getcwdb() | ||||
if testdescs and pathname: | if testdescs and pathname: | ||||
self._outputdir = os.path.join(self._outputdir, pathname) | self._outputdir = os.path.join(self._outputdir, pathname) | ||||
previoustimes = {} | previoustimes = {} | ||||
if self.options.order_by_runtime: | if self.options.order_by_runtime: | ||||
osenvironb.pop(b'PYOXIDIZED_INSTALLED_AS_HG', None) | osenvironb.pop(b'PYOXIDIZED_INSTALLED_AS_HG', None) | ||||
osenvironb[b"BINDIR"] = self._bindir | osenvironb[b"BINDIR"] = self._bindir | ||||
osenvironb[b"PYTHON"] = PYTHON | osenvironb[b"PYTHON"] = PYTHON | ||||
fileb = _sys2bytes(__file__) | fileb = _sys2bytes(__file__) | ||||
runtestdir = os.path.abspath(os.path.dirname(fileb)) | runtestdir = os.path.abspath(os.path.dirname(fileb)) | ||||
osenvironb[b'RUNTESTDIR'] = runtestdir | osenvironb[b'RUNTESTDIR'] = runtestdir | ||||
osenvironb[b'RUNTESTDIR_FORWARD_SLASH'] = osenvironb[b'RUNTESTDIR'].replace(os.sep.encode('ascii'), b'/') | |||||
if PYTHON3: | if PYTHON3: | ||||
sepb = _sys2bytes(os.pathsep) | sepb = _sys2bytes(os.pathsep) | ||||
else: | else: | ||||
sepb = os.pathsep | sepb = os.pathsep | ||||
path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb) | path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb) | ||||
if os.path.islink(__file__): | if os.path.islink(__file__): | ||||
# test helper will likely be at the end of the symlink | # test helper will likely be at the end of the symlink | ||||
realfile = os.path.realpath(fileb) | realfile = os.path.realpath(fileb) |
#testcases skip-detection fail-if-detected | #testcases skip-detection fail-if-detected | ||||
Test situations that "should" only be reproducible: | Test situations that "should" only be reproducible: | ||||
- on networked filesystems, or | - on networked filesystems, or | ||||
- user using `hg debuglocks` to eliminate the lock file, or | - user using `hg debuglocks` to eliminate the lock file, or | ||||
- something (that doesn't respect the lock file) writing to the .hg directory | - something (that doesn't respect the lock file) writing to the .hg directory | ||||
while we're running | while we're running | ||||
$ hg init a | $ hg init a | ||||
$ cd a | $ cd a | ||||
$ cat > "$TESTTMP/waitlock_editor.sh" <<EOF | $ cat > "$TESTTMP_FORWARD_SLASH/waitlock_editor.sh" <<EOF | ||||
> [ -n "\${WAITLOCK_ANNOUNCE:-}" ] && touch "\${WAITLOCK_ANNOUNCE}" | > [ -n "\${WAITLOCK_ANNOUNCE:-}" ] && touch "\${WAITLOCK_ANNOUNCE}" | ||||
> f="\${WAITLOCK_FILE}" | > f="\${WAITLOCK_FILE}" | ||||
> start=\`date +%s\` | > start=\`date +%s\` | ||||
> timeout=5 | > timeout=5 | ||||
> $RUNTESTDIR/testlib/wait-on-file "\$timeout" "\$f" | > "$RUNTESTDIR_FORWARD_SLASH/testlib/wait-on-file" "\$timeout" "\$f" | ||||
> if [ \$# -gt 1 ]; then | > if [ \$# -gt 1 ]; then | ||||
> cat "\$@" | > cat "\$@" | ||||
> fi | > fi | ||||
> EOF | > EOF | ||||
Things behave differently if we don't already have a 00changelog.i file when | Things behave differently if we don't already have a 00changelog.i file when | ||||
this all starts, so let's make one. | this all starts, so let's make one. | ||||
$ echo r0 > r0 | $ echo r0 > r0 | ||||
$ hg commit -qAm 'r0' | $ hg commit -qAm 'r0' | ||||
Start an hg commit that will take a while | Start an hg commit that will take a while | ||||
$ EDITOR_STARTED="$(pwd)/.editor_started" | $ EDITOR_STARTED="$TESTTMP_FORWARD_SLASH/a/.editor_started" | ||||
$ MISCHIEF_MANAGED="$(pwd)/.mischief_managed" | $ MISCHIEF_MANAGED="$TESTTMP_FORWARD_SLASH/a/.mischief_managed" | ||||
$ JOBS_FINISHED="$(pwd)/.jobs_finished" | $ JOBS_FINISHED="$TESTTMP_FORWARD_SLASH/a/.jobs_finished" | ||||
#if fail-if-detected | #if fail-if-detected | ||||
$ cat >> .hg/hgrc << EOF | $ cat >> .hg/hgrc << EOF | ||||
> [debug] | > [debug] | ||||
> revlog.verifyposition.changelog = fail | > revlog.verifyposition.changelog = fail | ||||
> EOF | > EOF | ||||
#endif | #endif | ||||
$ cat >> .hg/hgrc << EOF | $ cat >> .hg/hgrc << EOF | ||||
> [ui] | > [ui] | ||||
> editor=sh $TESTTMP/waitlock_editor.sh | > editor=sh $TESTTMP_FORWARD_SLASH/waitlock_editor.sh | ||||
> EOF | > EOF | ||||
$ echo foo > foo | $ echo foo > foo | ||||
$ (unset HGEDITOR; | $ (unset HGEDITOR; | ||||
> WAITLOCK_ANNOUNCE="${EDITOR_STARTED}" \ | > WAITLOCK_ANNOUNCE="${EDITOR_STARTED}" \ | ||||
> WAITLOCK_FILE="${MISCHIEF_MANAGED}" \ | > WAITLOCK_FILE="${MISCHIEF_MANAGED}" \ | ||||
> hg commit -qAm 'r1 (foo)' --edit foo > .foo_commit_out 2>&1 ; touch "${JOBS_FINISHED}") & | > hg commit -qAm 'r1 (foo)' --edit foo > .foo_commit_out 2>&1 ; touch "${JOBS_FINISHED}") & | ||||
Wait for the "editor" to actually start | Wait for the "editor" to actually start | ||||
$ sh "$RUNTESTDIR/testlib/wait-on-file" 5 "${EDITOR_STARTED}" | $ sh "$RUNTESTDIR_FORWARD_SLASH/testlib/wait-on-file" 5 "${EDITOR_STARTED}" | ||||
$ cat >> .hg/hgrc << EOF | $ cat >> .hg/hgrc << EOF | ||||
> [ui] | > [ui] | ||||
> editor= | > editor= | ||||
> EOF | > EOF | ||||
Break the locks, and make another commit. | Break the locks, and make another commit. | ||||
$ hg debuglocks -LW | $ hg debuglocks -LW | ||||
$ echo bar > bar | $ echo bar > bar | ||||
$ hg commit -qAm 'r2 (bar)' bar | $ hg commit -qAm 'r2 (bar)' bar | ||||
$ hg debugrevlogindex -c | $ hg debugrevlogindex -c | ||||
rev linkrev nodeid p1 p2 | rev linkrev nodeid p1 p2 | ||||
0 0 222799e2f90b 000000000000 000000000000 | 0 0 222799e2f90b 000000000000 000000000000 | ||||
1 1 6f124f6007a0 222799e2f90b 000000000000 | 1 1 6f124f6007a0 222799e2f90b 000000000000 | ||||
Awaken the editor from that first commit | Awaken the editor from that first commit | ||||
$ touch "${MISCHIEF_MANAGED}" | $ touch "${MISCHIEF_MANAGED}" | ||||
And wait for it to finish | And wait for it to finish | ||||
$ WAITLOCK_FILE="${JOBS_FINISHED}" sh "$TESTTMP/waitlock_editor.sh" | $ WAITLOCK_FILE="${JOBS_FINISHED}" sh "$TESTTMP_FORWARD_SLASH/waitlock_editor.sh" | ||||
#if skip-detection | #if skip-detection | ||||
(Ensure there was no output) | (Ensure there was no output) | ||||
$ cat .foo_commit_out | $ cat .foo_commit_out | ||||
And observe a corrupted repository -- rev 2's linkrev is 1, which should never | And observe a corrupted repository -- rev 2's linkrev is 1, which should never | ||||
happen for the changelog (the linkrev should always refer to itself). | happen for the changelog (the linkrev should always refer to itself). | ||||
$ hg debugrevlogindex -c | $ hg debugrevlogindex -c | ||||
rev linkrev nodeid p1 p2 | rev linkrev nodeid p1 p2 |