tests/test-nointerrupt.t
author Simon Sapin <simon.sapin@octobus.net>
Fri, 21 Jan 2022 17:54:03 +0100
changeset 48745 94e36b230990
parent 48255 8c34edb1ad10
child 49446 8c75ae3f0eea
permissions -rw-r--r--
status: prefer relative paths in Rust code … when the repository root is under the current directory, so the kernel needs to traverse fewer directory in every call to `read_dir` or `symlink_metadata`. Better yet would be to use libc functions like `openat` and `fstatat` to remove such repeated traversals entirely, but the standard library does not provide APIs based on those. Maybe with a crate like https://crates.io/crates/openat instead? Benchmarks of `rhg status` show that this patch is neutral in some configurations, and makes the command up to ~20% faster in others. Below is semi-arbitrary subset of results. The four numeric columns are: time (in seconds) with this changeset’s parent, time with this changeset, time difference (negative is better), time ratio (less than 1 is better). ``` mercurial-dirstate-v1 | default-plain-clean.no-iu.pbr | 0.0061 -> 0.0059: -0.0002 (0.97) mercurial-dirstate-v2 | default-plain-clean.no-iu.pbr | 0.0029 -> 0.0028: -0.0001 (0.97) mozilla-dirstate-v1 | default-plain-clean.no-iu.pbr | 0.2110 -> 0.2102: -0.0007 (1.00) mozilla-dirstate-v2 | default-copies-clean.ignored.pbr | 0.0489 -> 0.0401: -0.0088 (0.82) mozilla-dirstate-v2 | default-copies-clean.no-iu.pbr | 0.0479 -> 0.0393: -0.0085 (0.82) mozilla-dirstate-v2 | default-copies-large.all.pbr | 0.1262 -> 0.1210: -0.0051 (0.96) mozilla-dirstate-v2 | default-copies-small.ignored-unknown.pbr | 0.1262 -> 0.1200: -0.0062 (0.95) mozilla-dirstate-v2 | default-copies-small.ignored.pbr | 0.0536 -> 0.0417: -0.0119 (0.78) mozilla-dirstate-v2 | default-copies-small.no-iu.pbr | 0.0482 -> 0.0393: -0.0089 (0.81) mozilla-dirstate-v2 | default-plain-clean.ignored.pbr | 0.0518 -> 0.0402: -0.0116 (0.78) mozilla-dirstate-v2 | default-plain-clean.no-iu.pbr | 0.0481 -> 0.0392: -0.0088 (0.82) mozilla-dirstate-v2 | default-plain-large.all.pbr | 0.1271 -> 0.1218: -0.0052 (0.96) mozilla-dirstate-v2 | default-plain-small.ignored-unknown.pbr | 0.1225 -> 0.1202: -0.0022 (0.98) mozilla-dirstate-v2 | default-plain-small.ignored.pbr | 0.0510 -> 0.0418: -0.0092 (0.82) mozilla-dirstate-v2 | default-plain-small.no-iu.pbr | 0.0480 -> 0.0394: -0.0086 (0.82) netbeans-dirstate-v1 | default-plain-clean.no-iu.pbr | 0.1442 -> 0.1422: -0.0020 (0.99) netbeans-dirstate-v2 | default-plain-clean.no-iu.pbr | 0.0325 -> 0.0282: -0.0043 (0.87) ``` Differential Revision: https://phab.mercurial-scm.org/D12175

#require no-windows no-rhg

XXX-RHG this test hangs if `hg` is really `rhg`. This was hidden by the use of
`alias hg=rhg` by run-tests.py. With such alias removed, this test is revealed
buggy. This need to be resolved sooner than later.

Dummy extension simulating unsafe long running command
  $ SYNC_FILE="$TESTTMP/sync-file"
  $ export SYNC_FILE
  $ DONE_FILE="$TESTTMP/done-file"
  $ export DONE_FILE
  $ 
  $ cat > wait_ext.py <<EOF
  > import os
  > import time
  > 
  > from mercurial.i18n import _
  > from mercurial import registrar
  > from mercurial import testing
  > 
  > cmdtable = {}
  > command = registrar.command(cmdtable)
  > 
  > @command(b'wait-signal', [], _(b'SYNC_FILE DONE_FILE'), norepo=True)
  > def sleep(ui, sync_file=b"$SYNC_FILE", done_file=b"$DONE_FILE", **opts):
  >     start = time.time()
  >     with ui.uninterruptible():
  >         testing.write_file(sync_file, b'%d' % os.getpid())
  >         testing.wait_file(done_file)
  >         # make sure we get rescheduled and the signal get a chance to be handled
  >         time.sleep(0.1)
  >         ui.warn(b"end of unsafe operation\n")
  >     ui.warn(b"%d second(s) passed\n" % int(time.time() - start))
  > EOF

  $ cat > send-signal.sh << EOF
  > #!/bin/sh
  > SIG=\$1
  > if [ -z "\$SIG" ]; then
  >    echo "send-signal.sh requires one argument" >&2
  >    exit 1
  > fi
  > "$RUNTESTDIR/testlib/wait-on-file" 10 "$SYNC_FILE" || exit 2
  > kill -s \$SIG \`cat "$SYNC_FILE"\`
  > sleep 1
  > touch "$DONE_FILE"
  > EOF

#if no-windows
  $ chmod +x send-signal.sh
#endif

Kludge to emulate timeout(1) which is not generally available.

Set up repository
  $ hg init repo
  $ cd repo
  $ cat >> $HGRCPATH << EOF
  > [extensions]
  > wait_ext = $TESTTMP/wait_ext.py
  > EOF


Test ctrl-c
  $ rm -f $SYNC_FILE $DONE_FILE
  $ sh -c "../send-signal.sh INT" &
  $ hg wait-signal
  interrupted!
  [255]

  $ cat >> $HGRCPATH << EOF
  > [experimental]
  > nointerrupt = yes
  > EOF

  $ rm -f $SYNC_FILE $DONE_FILE
  $ sh -c "../send-signal.sh INT" &
  $ hg wait-signal
  interrupted!
  [255]

  $ cat >> $HGRCPATH << EOF
  > [experimental]
  > nointerrupt-interactiveonly = False
  > EOF

  $ rm -f $SYNC_FILE $DONE_FILE
  $ sh -c "../send-signal.sh INT" &
  $ hg wait-signal
  shutting down cleanly
  press ^C again to terminate immediately (dangerous)
  end of unsafe operation
  interrupted!
  [255]