tests/run-tests.py
author David Soria Parra <dsp@experimentalworks.net>
Thu, 29 Aug 2013 09:22:13 -0700
branchstable
changeset 1295 8e66ac9c0f0e
parent 1293 6e9bfd51bc6f
child 1298 d69c1db7cf8b
permissions -rwxr-xr-x
shelve: add a shelve extension to save/restore working changes This extension saves shelved changes using a temporary draft commit, and bundles the temporary commit and its draft ancestors, then strips them. This strategy makes it possible to use Mercurial's bundle and merge machinery to resolve conflicts if necessary when unshelving, even when the destination commit or its ancestors have been amended, squashed, or evolved. (Once a change has been unshelved, its associated unbundled commits are either rolled back or stripped.) Storing the shelved change as a bundle also avoids the difficulty that hidden commits would cause, of making it impossible to amend the parent if it is a draft commits (a common scenario). Although this extension shares its name and some functionality with the third party hgshelve extension, it has little else in common. Notably, the hgshelve extension shelves changes as unified diffs, which makes conflict resolution a matter of finding .rej files and conflict markers, and cleaning up the mess by hand. We do not yet allow hunk-level choosing of changes to record. Compared to the hgshelve extension, this is a small regression in usability, but we hope to integrate that at a later point, once the record machinery becomes more reusable and robust. [ original upstream message ]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     1
#!/usr/bin/env python
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     2
#
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     3
# run-tests.py - Run a set of tests on Mercurial
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     4
#
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     5
# Copyright 2006 Matt Mackall <mpm@selenic.com>
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     6
#
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     7
# This software may be used and distributed according to the terms of the
674
0efa9d6ac11f Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 670
diff changeset
     8
# GNU General Public License version 2 or any later version.
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
     9
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    10
# Modifying this script is tricky because it has many modes:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    11
#   - serial (default) vs parallel (-jN, N > 1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    12
#   - no coverage (default) vs coverage (-c, -C, -s)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    13
#   - temp install (default) vs specific hg script (--with-hg, --local)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    14
#   - tests are a mix of shell scripts and Python scripts
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    15
#
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    16
# If you change this script, it is recommended that you ensure you
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    17
# haven't broken it by running it in various modes with a representative
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    18
# sample of test scripts.  For example:
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
    19
#
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    20
#  1) serial, no coverage, temp install:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    21
#      ./run-tests.py test-s*
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    22
#  2) serial, no coverage, local hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    23
#      ./run-tests.py --local test-s*
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    24
#  3) serial, coverage, temp install:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    25
#      ./run-tests.py -c test-s*
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    26
#  4) serial, coverage, local hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    27
#      ./run-tests.py -c --local test-s*      # unsupported
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    28
#  5) parallel, no coverage, temp install:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    29
#      ./run-tests.py -j2 test-s*
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    30
#  6) parallel, no coverage, local hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    31
#      ./run-tests.py -j2 --local test-s*
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    32
#  7) parallel, coverage, temp install:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    33
#      ./run-tests.py -j2 -c test-s*          # currently broken
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
    34
#  8) parallel, coverage, local install:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    35
#      ./run-tests.py -j2 -c --local test-s*  # unsupported (and broken)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
    36
#  9) parallel, custom tmp dir:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
    37
#      ./run-tests.py -j2 --tmpdir /tmp/myhgtests
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    38
#
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    39
# (You could use any subset of the tests: test-s* happens to match
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    40
# enough that it's worth doing parallel runs, few enough that it
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    41
# completes fairly quickly, includes both shell and Python scripts, and
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    42
# includes some scripts that run daemon processes.)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    43
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
    44
from distutils import version
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    45
import difflib
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    46
import errno
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    47
import optparse
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    48
import os
726
f7050b041b5f pylint, pyflakes: remove unused or duplicate imports
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 725
diff changeset
    49
import shutil
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    50
import subprocess
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    51
import signal
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    52
import sys
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    53
import tempfile
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    54
import time
1212
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
    55
import random
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
    56
import re
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
    57
import threading
1126
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1094
diff changeset
    58
import killdaemons as killmod
1171
5af439678b99 run-tests: support running tests in parallel on windows
Bryan O'Sullivan <bryano@fb.com>
parents: 1170
diff changeset
    59
import Queue as queue
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    60
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    61
processlock = threading.Lock()
1281
3dc7d29a42e9 run-tests: lock popen wait/poll
Brendan Cully <brendan@kublai.com>
parents: 1280
diff changeset
    62
1283
e1d949ad7cda run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 1282
diff changeset
    63
# subprocess._cleanup can race with any Popen.wait or Popen.poll on py24
e1d949ad7cda run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 1282
diff changeset
    64
# http://bugs.python.org/issue1731717 for details. We shouldn't be producing
e1d949ad7cda run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 1282
diff changeset
    65
# zombies but it's pretty harmless even if we do.
e1d949ad7cda run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 1282
diff changeset
    66
if sys.version_info[1] < 5:
e1d949ad7cda run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 1282
diff changeset
    67
    subprocess._cleanup = lambda: None
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    68
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    69
closefds = os.name == 'posix'
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
    70
def Popen4(cmd, wd, timeout, env=None):
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    71
    processlock.acquire()
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
    72
    p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env,
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    73
                         close_fds=closefds,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    74
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    75
                         stderr=subprocess.STDOUT)
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    76
    processlock.release()
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    77
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    78
    p.fromchild = p.stdout
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    79
    p.tochild = p.stdin
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    80
    p.childerr = p.stderr
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    81
944
37aff8ccb33e run-tests: ignore timeout when Popen.terminate is unavailable
Patrick Mezard <pmezard@gmail.com>
parents: 943
diff changeset
    82
    p.timeout = False
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    83
    if timeout:
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    84
        def t():
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    85
            start = time.time()
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    86
            while time.time() - start < timeout and p.returncode is None:
1059
1745fd2dd308 tests: shorten post-test sleeps
Matt Mackall <mpm@selenic.com>
parents: 1046
diff changeset
    87
                time.sleep(.1)
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    88
            p.timeout = True
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    89
            if p.returncode is None:
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
    90
                terminate(p)
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    91
        threading.Thread(target=t).start()
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    92
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    93
    return p
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    94
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    95
# reserved exit code to skip test (used by hghave)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    96
SKIPPED_STATUS = 80
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    97
SKIPPED_PREFIX = 'skipped: '
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    98
FAILED_PREFIX  = 'hghave check failed: '
1016
b4ca7adb4bf1 run-tests: convert windows paths to unix
Mads Kiilerich <mads@kiilerich.com>
parents: 1015
diff changeset
    99
PYTHON = sys.executable.replace('\\', '/')
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   100
IMPL_PATH = 'PYTHONPATH'
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   101
if 'java' in sys.platform:
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   102
    IMPL_PATH = 'JYTHONPATH'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   103
1169
28f06763bfb2 run-tests: check for the correct python when starting
Bryan O'Sullivan <bryano@fb.com>
parents: 1168
diff changeset
   104
requiredtools = [os.path.basename(sys.executable), "diff", "grep", "unzip",
28f06763bfb2 run-tests: check for the correct python when starting
Bryan O'Sullivan <bryano@fb.com>
parents: 1168
diff changeset
   105
                 "gunzip", "bunzip2", "sed"]
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   106
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   107
defaults = {
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   108
    'jobs': ('HGTEST_JOBS', 1),
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   109
    'timeout': ('HGTEST_TIMEOUT', 180),
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   110
    'port': ('HGTEST_PORT', 20059),
1045
0a2285b90e22 tests: let run-tests.py default to use 'sh' in $PATH instead of '/bin/sh'
Mads Kiilerich <mads@kiilerich.com>
parents: 1044
diff changeset
   111
    'shell': ('HGTEST_SHELL', 'sh'),
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   112
}
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   113
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   114
def parselistfiles(files, listtype, warn=True):
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   115
    entries = dict()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   116
    for filename in files:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   117
        try:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   118
            path = os.path.expanduser(os.path.expandvars(filename))
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   119
            f = open(path, "r")
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   120
        except IOError, err:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   121
            if err.errno != errno.ENOENT:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   122
                raise
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   123
            if warn:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   124
                print "warning: no such %s file: %s" % (listtype, filename)
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   125
            continue
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   126
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   127
        for line in f.readlines():
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   128
            line = line.split('#', 1)[0].strip()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   129
            if line:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   130
                entries[line] = filename
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   131
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   132
        f.close()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   133
    return entries
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   134
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   135
def parseargs():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   136
    parser = optparse.OptionParser("%prog [options] [tests]")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   137
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   138
    # keep these sorted
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   139
    parser.add_option("--blacklist", action="append",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   140
        help="skip tests listed in the specified blacklist file")
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   141
    parser.add_option("--whitelist", action="append",
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   142
        help="always run tests listed in the specified whitelist file")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   143
    parser.add_option("-C", "--annotate", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   144
        help="output files annotated with coverage")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   145
    parser.add_option("-c", "--cover", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   146
        help="print a test coverage report")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   147
    parser.add_option("-d", "--debug", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   148
        help="debug mode: write output of test scripts to console"
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   149
             " rather than capturing and diff'ing it (disables timeout)")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   150
    parser.add_option("-f", "--first", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   151
        help="exit on the first test failure")
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   152
    parser.add_option("-H", "--htmlcov", action="store_true",
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   153
        help="create an HTML report of the coverage of the files")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   154
    parser.add_option("--inotify", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   155
        help="enable inotify extension when running tests")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   156
    parser.add_option("-i", "--interactive", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   157
        help="prompt to accept changed output")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   158
    parser.add_option("-j", "--jobs", type="int",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   159
        help="number of jobs to run in parallel"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   160
             " (default: $%s or %d)" % defaults['jobs'])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   161
    parser.add_option("--keep-tmpdir", action="store_true",
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   162
        help="keep temporary directory after running tests")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   163
    parser.add_option("-k", "--keywords",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   164
        help="run tests matching keywords")
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   165
    parser.add_option("-l", "--local", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   166
        help="shortcut for --with-hg=<testdir>/../hg")
1261
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
   167
    parser.add_option("--loop", action="store_true",
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
   168
        help="loop tests repeatedly")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   169
    parser.add_option("-n", "--nodiff", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   170
        help="skip showing test changes")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   171
    parser.add_option("-p", "--port", type="int",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   172
        help="port on which servers should listen"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   173
             " (default: $%s or %d)" % defaults['port'])
1165
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   174
    parser.add_option("--compiler", type="string",
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   175
        help="compiler to build with")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   176
    parser.add_option("--pure", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   177
        help="use pure Python code instead of C extensions")
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   178
    parser.add_option("-R", "--restart", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   179
        help="restart at last error")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   180
    parser.add_option("-r", "--retest", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   181
        help="retest failed tests")
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   182
    parser.add_option("-S", "--noskips", action="store_true",
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   183
        help="don't report skip tests verbosely")
932
eb562ea207c3 run-tests: add --shell command line flag
Martin Geisler <mg@lazybytes.net>
parents: 931
diff changeset
   184
    parser.add_option("--shell", type="string",
eb562ea207c3 run-tests: add --shell command line flag
Martin Geisler <mg@lazybytes.net>
parents: 931
diff changeset
   185
        help="shell to use (default: $%s or %s)" % defaults['shell'])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   186
    parser.add_option("-t", "--timeout", type="int",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   187
        help="kill errant tests after TIMEOUT seconds"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   188
             " (default: $%s or %d)" % defaults['timeout'])
1159
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   189
    parser.add_option("--time", action="store_true",
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   190
        help="time how long each test takes")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   191
    parser.add_option("--tmpdir", type="string",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   192
        help="run tests in the given temporary directory"
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   193
             " (implies --keep-tmpdir)")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   194
    parser.add_option("-v", "--verbose", action="store_true",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   195
        help="output verbose messages")
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   196
    parser.add_option("--view", type="string",
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   197
        help="external diff viewer")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   198
    parser.add_option("--with-hg", type="string",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   199
        metavar="HG",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   200
        help="test using specified hg script rather than a "
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   201
             "temporary installation")
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   202
    parser.add_option("-3", "--py3k-warnings", action="store_true",
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   203
        help="enable Py3k warnings on Python 2.6+")
926
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   204
    parser.add_option('--extra-config-opt', action="append",
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   205
                      help='set the given config opt in the test hgrc')
1221
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
   206
    parser.add_option('--random', action="store_true",
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
   207
                      help='run tests in random order')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   208
931
b56e95db7ac5 run-tests: use type of default to convert environment variable
Martin Geisler <mg@lazybytes.net>
parents: 930
diff changeset
   209
    for option, (envvar, default) in defaults.items():
b56e95db7ac5 run-tests: use type of default to convert environment variable
Martin Geisler <mg@lazybytes.net>
parents: 930
diff changeset
   210
        defaults[option] = type(default)(os.environ.get(envvar, default))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   211
    parser.set_defaults(**defaults)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   212
    (options, args) = parser.parse_args()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   213
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   214
    # jython is always pure
722
85da4926cf39 run-tests: force to test pure on pypy as well
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 721
diff changeset
   215
    if 'java' in sys.platform or '__pypy__' in sys.modules:
721
1dbc96b10ebd Fix run-tests.py -jX after 2ed667a9dfcb
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 720
diff changeset
   216
        options.pure = True
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   217
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   218
    if options.with_hg:
1046
2890e1f3d8e4 run-tests: expand user in --with-hg
Mads Kiilerich <mads@kiilerich.com>
parents: 1045
diff changeset
   219
        options.with_hg = os.path.expanduser(options.with_hg)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   220
        if not (os.path.isfile(options.with_hg) and
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   221
                os.access(options.with_hg, os.X_OK)):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   222
            parser.error('--with-hg must specify an executable hg script')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   223
        if not os.path.basename(options.with_hg) == 'hg':
951
0af8a73dfe14 run-tests: print a newline after all warnings
Thomas Arendsen Hein <thomas@intevation.de>
parents: 947
diff changeset
   224
            sys.stderr.write('warning: --with-hg should specify an hg script\n')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   225
    if options.local:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   226
        testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   227
        hgbin = os.path.join(os.path.dirname(testdir), 'hg')
1065
c1d229864cd3 tests: don't require 'hg' without extension on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1059
diff changeset
   228
        if os.name != 'nt' and not os.access(hgbin, os.X_OK):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   229
            parser.error('--local specified, but %r not found or not executable'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   230
                         % hgbin)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   231
        options.with_hg = hgbin
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   232
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   233
    options.anycoverage = options.cover or options.annotate or options.htmlcov
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   234
    if options.anycoverage:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   235
        try:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   236
            import coverage
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   237
            covver = version.StrictVersion(coverage.__version__).version
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   238
            if covver < (3, 3):
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   239
                parser.error('coverage options require coverage 3.3 or later')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   240
        except ImportError:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   241
            parser.error('coverage options now require the coverage package')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   242
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   243
    if options.anycoverage and options.local:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   244
        # this needs some path mangling somewhere, I guess
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   245
        parser.error("sorry, coverage options do not work when --local "
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   246
                     "is specified")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   247
1238
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   248
    global verbose
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   249
    if options.verbose:
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
   250
        verbose = ''
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   251
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   252
    if options.tmpdir:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   253
        options.tmpdir = os.path.expanduser(options.tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   254
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   255
    if options.jobs < 1:
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   256
        parser.error('--jobs must be positive')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   257
    if options.interactive and options.debug:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   258
        parser.error("-i/--interactive and -d/--debug are incompatible")
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   259
    if options.debug:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   260
        if options.timeout != defaults['timeout']:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   261
            sys.stderr.write(
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   262
                'warning: --timeout option ignored with --debug\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   263
        options.timeout = 0
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   264
    if options.py3k_warnings:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   265
        if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   266
            parser.error('--py3k-warnings can only be used on Python 2.6+')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   267
    if options.blacklist:
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   268
        options.blacklist = parselistfiles(options.blacklist, 'blacklist')
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   269
    if options.whitelist:
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
   270
        options.whitelisted = parselistfiles(options.whitelist, 'whitelist')
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   271
    else:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   272
        options.whitelisted = {}
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   273
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   274
    return (options, args)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   275
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   276
def rename(src, dst):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   277
    """Like os.rename(), trade atomicity and opened files friendliness
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   278
    for existing destination support.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   279
    """
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   280
    shutil.copy(src, dst)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   281
    os.remove(src)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   282
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   283
def parsehghaveoutput(lines):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   284
    '''Parse hghave log lines.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   285
    Return tuple of lists (missing, failed):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   286
      * the missing/unknown features
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   287
      * the features for which existence check failed'''
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   288
    missing = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   289
    failed = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   290
    for line in lines:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   291
        if line.startswith(SKIPPED_PREFIX):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   292
            line = line.splitlines()[0]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   293
            missing.append(line[len(SKIPPED_PREFIX):])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   294
        elif line.startswith(FAILED_PREFIX):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   295
            line = line.splitlines()[0]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   296
            failed.append(line[len(FAILED_PREFIX):])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   297
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   298
    return missing, failed
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   299
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   300
def showdiff(expected, output, ref, err):
923
8212da2b01eb run-tests: print a new line before writing the diff
Idan Kamara <idankk86@gmail.com>
parents: 921
diff changeset
   301
    print
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   302
    for line in difflib.unified_diff(expected, output, ref, err):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   303
        sys.stdout.write(line)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   304
1238
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   305
verbose = False
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   306
def vlog(*msg):
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   307
    if verbose is not False:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   308
        iolock.acquire()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   309
        if verbose:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   310
            print verbose,
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   311
        for m in msg:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   312
            print m,
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   313
        print
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   314
        sys.stdout.flush()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   315
        iolock.release()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   316
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   317
def log(*msg):
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   318
    iolock.acquire()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   319
    if verbose:
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   320
        print verbose,
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   321
    for m in msg:
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   322
        print m,
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   323
    print
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   324
    sys.stdout.flush()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   325
    iolock.release()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   326
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   327
def findprogram(program):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   328
    """Search PATH for a executable program"""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   329
    for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   330
        name = os.path.join(p, program)
942
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   331
        if os.name == 'nt' or os.access(name, os.X_OK):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   332
            return name
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   333
    return None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   334
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   335
def createhgrc(path, options):
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   336
    # create a fresh hgrc
1265
ae952fb9707f run-tests: open hgrc file only for writing
Simon Heimberg <simohe@besonet.ch>
parents: 1263
diff changeset
   337
    hgrc = open(path, 'w')
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   338
    hgrc.write('[ui]\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   339
    hgrc.write('slash = True\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   340
    hgrc.write('interactive = False\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   341
    hgrc.write('[defaults]\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   342
    hgrc.write('backout = -d "0 0"\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   343
    hgrc.write('commit = -d "0 0"\n')
1295
8e66ac9c0f0e shelve: add a shelve extension to save/restore working changes
David Soria Parra <dsp@experimentalworks.net>
parents: 1293
diff changeset
   344
    hgrc.write('shelve = --date "0 0"\n')
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   345
    hgrc.write('tag = -d "0 0"\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   346
    if options.inotify:
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   347
        hgrc.write('[extensions]\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   348
        hgrc.write('inotify=\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   349
        hgrc.write('[inotify]\n')
1245
605be28ee4d0 run-tests: move DAEMON_PIDS to env
Matt Mackall <mpm@selenic.com>
parents: 1244
diff changeset
   350
        hgrc.write('pidfile=daemon.pids')
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   351
        hgrc.write('appendpid=True\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   352
    if options.extra_config_opt:
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   353
        for opt in options.extra_config_opt:
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   354
            section, key = opt.split('.', 1)
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   355
            assert '=' in key, ('extra config opt %s must '
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   356
                                'have an = for assignment' % opt)
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   357
            hgrc.write('[%s]\n%s\n' % (section, key))
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   358
    hgrc.close()
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   359
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   360
def createenv(options, testtmp, threadtmp, port):
1247
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   361
    env = os.environ.copy()
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   362
    env['TESTTMP'] = testtmp
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   363
    env['HOME'] = testtmp
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   364
    env["HGPORT"] = str(port)
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   365
    env["HGPORT1"] = str(port + 1)
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   366
    env["HGPORT2"] = str(port + 2)
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   367
    env["HGRCPATH"] = os.path.join(threadtmp, '.hgrc')
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   368
    env["DAEMON_PIDS"] = os.path.join(threadtmp, 'daemon.pids')
1250
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   369
    env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   370
    env["HGMERGE"] = "internal:merge"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   371
    env["HGUSER"]   = "test"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   372
    env["HGENCODING"] = "ascii"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   373
    env["HGENCODINGMODE"] = "strict"
1247
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   374
1248
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   375
    # Reset some environment variables to well-known values so that
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   376
    # the tests produce repeatable output.
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   377
    env['LANG'] = env['LC_ALL'] = env['LANGUAGE'] = 'C'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   378
    env['TZ'] = 'GMT'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   379
    env["EMAIL"] = "Foo Bar <foo.bar@example.com>"
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   380
    env['COLUMNS'] = '80'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   381
    env['TERM'] = 'xterm'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   382
1249
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   383
    for k in ('HG HGPROF CDPATH GREP_OPTIONS http_proxy no_proxy ' +
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   384
              'NO_PROXY').split():
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   385
        if k in env:
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   386
            del env[k]
1248
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   387
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   388
    # unset env related to hooks
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   389
    for k in env.keys():
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   390
        if k.startswith('HG_'):
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   391
            del env[k]
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   392
1247
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   393
    return env
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   394
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   395
def checktools():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   396
    # Before we go any further, check for pre-requisite tools
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   397
    # stuff from coreutils (cat, rm, etc) are not tested
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   398
    for p in requiredtools:
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   399
        if os.name == 'nt' and not p.endswith('.exe'):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   400
            p += '.exe'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   401
        found = findprogram(p)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   402
        if found:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   403
            vlog("# Found prerequisite", p, "at", found)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   404
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   405
            print "WARNING: Did not find prerequisite tool: "+p
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   406
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   407
def terminate(proc):
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   408
    """Terminate subprocess (with fallback for Python versions < 2.6)"""
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   409
    vlog('# Terminating process %d' % proc.pid)
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   410
    try:
977
a50ed14997fc tests: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 975
diff changeset
   411
        getattr(proc, 'terminate', lambda : os.kill(proc.pid, signal.SIGTERM))()
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   412
    except OSError:
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   413
        pass
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   414
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   415
def killdaemons(pidfile):
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   416
    return killmod.killdaemons(pidfile, tryhard=False, remove=True,
1126
dbcb11553a3b run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 1094
diff changeset
   417
                               logfn=vlog)
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   418
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   419
def cleanup(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   420
    if not options.keep_tmpdir:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   421
        vlog("# Cleaning up HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   422
        shutil.rmtree(HGTMP, True)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   423
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   424
def usecorrectpython():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   425
    # some tests run python interpreter. they must use same
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   426
    # interpreter we use or bad things will happen.
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   427
    pyexename = sys.platform == 'win32' and 'python.exe' or 'python'
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   428
    if getattr(os, 'symlink', None):
1175
62cc0851c70f run-tests: fix whitespace nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 1174
diff changeset
   429
        vlog("# Making python executable in test path a symlink to '%s'" %
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   430
             sys.executable)
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   431
        mypython = os.path.join(BINDIR, pyexename)
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   432
        try:
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   433
            if os.readlink(mypython) == sys.executable:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   434
                return
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   435
            os.unlink(mypython)
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   436
        except OSError, err:
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   437
            if err.errno != errno.ENOENT:
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   438
                raise
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   439
        if findprogram(pyexename) != sys.executable:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   440
            try:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   441
                os.symlink(sys.executable, mypython)
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   442
            except OSError, err:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   443
                # child processes may race, which is harmless
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   444
                if err.errno != errno.EEXIST:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   445
                    raise
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   446
    else:
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   447
        exedir, exename = os.path.split(sys.executable)
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   448
        vlog("# Modifying search path to find %s as %s in '%s'" %
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   449
             (exename, pyexename, exedir))
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   450
        path = os.environ['PATH'].split(os.pathsep)
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   451
        while exedir in path:
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   452
            path.remove(exedir)
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   453
        os.environ['PATH'] = os.pathsep.join([exedir] + path)
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   454
        if not findprogram(pyexename):
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   455
            print "WARNING: Cannot find %s in search path" % pyexename
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   456
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   457
def installhg(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   458
    vlog("# Performing temporary installation of HG")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   459
    installerrs = os.path.join("tests", "install.err")
1165
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   460
    compiler = ''
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   461
    if options.compiler:
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   462
        compiler = '--compiler ' + options.compiler
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   463
    pure = options.pure and "--pure" or ""
1292
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   464
    py3 = ''
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   465
    if sys.version_info[0] == 3:
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   466
        py3 = '--c2to3'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   467
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   468
    # Run installer in hg root
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   469
    script = os.path.realpath(sys.argv[0])
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   470
    hgroot = os.path.dirname(os.path.dirname(script))
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   471
    os.chdir(hgroot)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   472
    nohome = '--home=""'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   473
    if os.name == 'nt':
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   474
        # The --home="" trick works only on OS where os.sep == '/'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   475
        # because of a distutils convert_path() fast-path. Avoid it at
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   476
        # least on Windows for now, deal with .pydistutils.cfg bugs
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   477
        # when they happen.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   478
        nohome = ''
1292
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   479
    cmd = ('%(exe)s setup.py %(py3)s %(pure)s clean --all'
1165
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   480
           ' build %(compiler)s --build-base="%(base)s"'
1164
8ed9a9f075f9 run-tests: make build command line less intimidating
Bryan O'Sullivan <bryano@fb.com>
parents: 1163
diff changeset
   481
           ' install --force --prefix="%(prefix)s" --install-lib="%(libdir)s"'
8ed9a9f075f9 run-tests: make build command line less intimidating
Bryan O'Sullivan <bryano@fb.com>
parents: 1163
diff changeset
   482
           ' --install-scripts="%(bindir)s" %(nohome)s >%(logfile)s 2>&1'
1292
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   483
           % dict(exe=sys.executable, py3=py3, pure=pure, compiler=compiler,
1164
8ed9a9f075f9 run-tests: make build command line less intimidating
Bryan O'Sullivan <bryano@fb.com>
parents: 1163
diff changeset
   484
                  base=os.path.join(HGTMP, "build"),
1166
d38c648869bb run-tests: fix an unnoticed check-code violation
Bryan O'Sullivan <bryano@fb.com>
parents: 1165
diff changeset
   485
                  prefix=INST, libdir=PYTHONDIR, bindir=BINDIR,
1164
8ed9a9f075f9 run-tests: make build command line less intimidating
Bryan O'Sullivan <bryano@fb.com>
parents: 1163
diff changeset
   486
                  nohome=nohome, logfile=installerrs))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   487
    vlog("# Running", cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   488
    if os.system(cmd) == 0:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   489
        if not options.verbose:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   490
            os.remove(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   491
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   492
        f = open(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   493
        for line in f:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   494
            print line,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   495
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   496
        sys.exit(1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   497
    os.chdir(TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   498
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   499
    usecorrectpython()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   500
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   501
    vlog("# Installing dummy diffstat")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   502
    f = open(os.path.join(BINDIR, 'diffstat'), 'w')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   503
    f.write('#!' + sys.executable + '\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   504
            'import sys\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   505
            'files = 0\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   506
            'for line in sys.stdin:\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   507
            '    if line.startswith("diff "):\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   508
            '        files += 1\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   509
            'sys.stdout.write("files patched: %d\\n" % files)\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   510
    f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   511
    os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   512
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   513
    if options.py3k_warnings and not options.anycoverage:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   514
        vlog("# Updating hg command to enable Py3k Warnings switch")
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   515
        f = open(os.path.join(BINDIR, 'hg'), 'r')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   516
        lines = [line.rstrip() for line in f]
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   517
        lines[0] += ' -3'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   518
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   519
        f = open(os.path.join(BINDIR, 'hg'), 'w')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   520
        for line in lines:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   521
            f.write(line + '\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   522
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   523
943
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   524
    hgbat = os.path.join(BINDIR, 'hg.bat')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   525
    if os.path.isfile(hgbat):
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   526
        # hg.bat expects to be put in bin/scripts while run-tests.py
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   527
        # installation layout put it in bin/ directly. Fix it
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   528
        f = open(hgbat, 'rb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   529
        data = f.read()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   530
        f.close()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   531
        if '"%~dp0..\python" "%~dp0hg" %*' in data:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   532
            data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   533
                                '"%~dp0python" "%~dp0hg" %*')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   534
            f = open(hgbat, 'wb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   535
            f.write(data)
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   536
            f.close()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   537
        else:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   538
            print 'WARNING: cannot fix hg.bat reference to python.exe'
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   539
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   540
    if options.anycoverage:
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   541
        custom = os.path.join(TESTDIR, 'sitecustomize.py')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   542
        target = os.path.join(PYTHONDIR, 'sitecustomize.py')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   543
        vlog('# Installing coverage trigger to %s' % target)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   544
        shutil.copyfile(custom, target)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   545
        rc = os.path.join(TESTDIR, '.coveragerc')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   546
        vlog('# Installing coverage rc to %s' % rc)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   547
        os.environ['COVERAGE_PROCESS_START'] = rc
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   548
        fn = os.path.join(INST, '..', '.coverage')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   549
        os.environ['COVERAGE_FILE'] = fn
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   550
1159
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   551
def outputtimes(options):
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   552
    vlog('# Producing time report')
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   553
    times.sort(key=lambda t: (t[1], t[0]), reverse=True)
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   554
    cols = '%7.3f   %s'
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   555
    print '\n%-7s   %s' % ('Time', 'Test')
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   556
    for test, timetaken in times:
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   557
        print cols % (timetaken, test)
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   558
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   559
def outputcoverage(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   560
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   561
    vlog('# Producing coverage report')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   562
    os.chdir(PYTHONDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   563
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   564
    def covrun(*args):
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   565
        cmd = 'coverage %s' % ' '.join(args)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   566
        vlog('# Running: %s' % cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   567
        os.system(cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   568
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   569
    covrun('-c')
1038
62b7a0759ee3 run-tests: use a list comprehension instead of map
Matt Mackall <mpm@selenic.com>
parents: 1037
diff changeset
   570
    omit = ','.join(os.path.join(x, '*') for x in [BINDIR, TESTDIR])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   571
    covrun('-i', '-r', '"--omit=%s"' % omit) # report
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   572
    if options.htmlcov:
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   573
        htmldir = os.path.join(TESTDIR, 'htmlcov')
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   574
        covrun('-i', '-b', '"--directory=%s"' % htmldir, '"--omit=%s"' % omit)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   575
    if options.annotate:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   576
        adir = os.path.join(TESTDIR, 'annotated')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   577
        if not os.path.isdir(adir):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   578
            os.mkdir(adir)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   579
        covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   580
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   581
def pytest(test, wd, options, replacements, env):
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   582
    py3kswitch = options.py3k_warnings and ' -3' or ''
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   583
    cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   584
    vlog("# Running", cmd)
1289
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   585
    if os.name == 'nt':
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   586
        replacements.append((r'\r\n', '\n'))
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   587
    return run(cmd, wd, options, replacements, env)
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   588
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   589
needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   590
escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   591
escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   592
escapemap.update({'\\': '\\\\', '\r': r'\r'})
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   593
def escapef(m):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   594
    return escapemap[m.group(0)]
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   595
def stringescape(s):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   596
    return escapesub(escapef, s)
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   597
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   598
def rematch(el, l):
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   599
    try:
1149
a3d0e19724c3 run-tests: alternative way of handling \r on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1143
diff changeset
   600
        # use \Z to ensure that the regex matches to the end of the string
1289
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   601
        if os.name == 'nt':
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   602
            return re.match(el + r'\r?\n\Z', l)
1149
a3d0e19724c3 run-tests: alternative way of handling \r on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1143
diff changeset
   603
        return re.match(el + r'\n\Z', l)
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   604
    except re.error:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   605
        # el is an invalid regex
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   606
        return False
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   607
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   608
def globmatch(el, l):
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   609
    # The only supported special characters are * and ? plus / which also
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   610
    # matches \ on windows. Escaping of these caracters is supported.
1215
62ff53b05730 tests: quickly check if the glob line already matches the output
Simon Heimberg <simohe@besonet.ch>
parents: 1212
diff changeset
   611
    if el + '\n' == l:
1284
3f370565e291 run-tests: test for os.altsep instead of os.name when checking \ for /
Simon Heimberg <simohe@besonet.ch>
parents: 1283
diff changeset
   612
        if os.altsep:
1216
192cebcd59a0 tests: inform on Windows about unnecessary glob lines
Simon Heimberg <simohe@besonet.ch>
parents: 1215
diff changeset
   613
            # matching on "/" is not needed for this line
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   614
            log("\nInfo, unnecessary glob: %s (glob)" % el)
1215
62ff53b05730 tests: quickly check if the glob line already matches the output
Simon Heimberg <simohe@besonet.ch>
parents: 1212
diff changeset
   615
        return True
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   616
    i, n = 0, len(el)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   617
    res = ''
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   618
    while i < n:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   619
        c = el[i]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   620
        i += 1
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   621
        if c == '\\' and el[i] in '*?\\/':
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   622
            res += el[i - 1:i + 1]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   623
            i += 1
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   624
        elif c == '*':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   625
            res += '.*'
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   626
        elif c == '?':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   627
            res += '.'
1284
3f370565e291 run-tests: test for os.altsep instead of os.name when checking \ for /
Simon Heimberg <simohe@besonet.ch>
parents: 1283
diff changeset
   628
        elif c == '/' and os.altsep:
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   629
            res += '[/\\\\]'
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   630
        else:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   631
            res += re.escape(c)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   632
    return rematch(res, l)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   633
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   634
def linematch(el, l):
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   635
    if el == l: # perfect match (fast)
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   636
        return True
1150
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   637
    if el:
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   638
        if el.endswith(" (esc)\n"):
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   639
            el = el[:-7].decode('string-escape') + '\n'
1289
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   640
        if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l:
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   641
            return True
1150
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   642
        if (el.endswith(" (re)\n") and rematch(el[:-6], l) or
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   643
            el.endswith(" (glob)\n") and globmatch(el[:-8], l)):
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   644
            return True
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   645
    return False
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   646
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   647
def tsttest(test, wd, options, replacements, env):
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   648
    # We generate a shell script which outputs unique markers to line
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   649
    # up script results with our source. These markers include input
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   650
    # line number and the last return code
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   651
    salt = "SALT" + str(time.time())
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   652
    def addsalt(line, inpython):
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   653
        if inpython:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   654
            script.append('%s %d 0\n' % (salt, line))
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   655
        else:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   656
            script.append('echo %s %s $?\n' % (salt, line))
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   657
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   658
    # After we run the shell script, we re-unify the script output
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   659
    # with non-active parts of the source, with synchronization by our
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   660
    # SALT line number markers. The after table contains the
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   661
    # non-active components, ordered by line number
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   662
    after = {}
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   663
    pos = prepos = -1
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   664
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   665
    # Expected shellscript output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   666
    expected = {}
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   667
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   668
    # We keep track of whether or not we're in a Python block so we
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   669
    # can generate the surrounding doctest magic
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   670
    inpython = False
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   671
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   672
    # True or False when in a true or false conditional section
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   673
    skipping = None
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   674
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   675
    def hghave(reqs):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   676
        # TODO: do something smarter when all other uses of hghave is gone
1090
e7e4ca624772 tests/run-tests: avoid C:/ in arguments
Adrian Buehlmann <adrian@cadifra.com>
parents: 1088
diff changeset
   677
        tdir = TESTDIR.replace('\\', '/')
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   678
        proc = Popen4('%s -c "%s/hghave %s"' %
1094
467eb2068e4a tests: use the right directory for running hghave from run-tests.py
Mads Kiilerich <mads@kiilerich.com>
parents: 1093
diff changeset
   679
                      (options.shell, tdir, ' '.join(reqs)), wd, 0)
1182
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   680
        stdout, stderr = proc.communicate()
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   681
        ret = proc.wait()
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   682
        if wifexited(ret):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   683
            ret = os.WEXITSTATUS(ret)
1182
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   684
        if ret == 2:
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   685
            print stdout
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   686
            sys.exit(1)
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   687
        return ret == 0
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   688
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   689
    f = open(test)
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   690
    t = f.readlines()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   691
    f.close()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   692
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   693
    script = []
1044
23c6e5d22e79 tests: add 'set -x' to the .t sh scripts in run-tests.py debug mode
Mads Kiilerich <mads@kiilerich.com>
parents: 1039
diff changeset
   694
    if options.debug:
23c6e5d22e79 tests: add 'set -x' to the .t sh scripts in run-tests.py debug mode
Mads Kiilerich <mads@kiilerich.com>
parents: 1039
diff changeset
   695
        script.append('set -x\n')
1033
8cbcb86e4fa8 tests: use an alias to make msys 'pwd' return paths with forward slashes
Mads Kiilerich <mads@kiilerich.com>
parents: 1022
diff changeset
   696
    if os.getenv('MSYSTEM'):
8cbcb86e4fa8 tests: use an alias to make msys 'pwd' return paths with forward slashes
Mads Kiilerich <mads@kiilerich.com>
parents: 1022
diff changeset
   697
        script.append('alias pwd="pwd -W"\n')
1210
02c4186c3aca run-tests: do not fail on empty tsttest file
Simon Heimberg <simohe@besonet.ch>
parents: 1208
diff changeset
   698
    n = 0
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   699
    for n, l in enumerate(t):
856
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   700
        if not l.endswith('\n'):
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   701
            l += '\n'
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   702
        if l.startswith('#if'):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   703
            if skipping is not None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   704
                after.setdefault(pos, []).append('  !!! nested #if\n')
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   705
            skipping = not hghave(l.split()[1:])
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   706
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   707
        elif l.startswith('#else'):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   708
            if skipping is None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   709
                after.setdefault(pos, []).append('  !!! missing #if\n')
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   710
            skipping = not skipping
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   711
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   712
        elif l.startswith('#endif'):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   713
            if skipping is None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   714
                after.setdefault(pos, []).append('  !!! missing #if\n')
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   715
            skipping = None
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   716
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   717
        elif skipping:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   718
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   719
        elif l.startswith('  >>> '): # python inlines
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   720
            after.setdefault(pos, []).append(l)
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   721
            prepos = pos
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   722
            pos = n
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   723
            if not inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   724
                # we've just entered a Python block, add the header
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   725
                inpython = True
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   726
                addsalt(prepos, False) # make sure we report the exit code
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   727
                script.append('%s -m heredoctest <<EOF\n' % PYTHON)
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   728
            addsalt(n, True)
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   729
            script.append(l[2:])
1085
a2e7456b162e run-tests: don't add python lines to expected dict
Adrian Buehlmann <adrian@cadifra.com>
parents: 1084
diff changeset
   730
        elif l.startswith('  ... '): # python inlines
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   731
            after.setdefault(prepos, []).append(l)
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   732
            script.append(l[2:])
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   733
        elif l.startswith('  $ '): # commands
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   734
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   735
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   736
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   737
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   738
            prepos = pos
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   739
            pos = n
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   740
            addsalt(n, False)
1093
660262879b48 tests: make .t tests stop immediately if a cd fails
Mads Kiilerich <mads@kiilerich.com>
parents: 1090
diff changeset
   741
            cmd = l[4:].split()
660262879b48 tests: make .t tests stop immediately if a cd fails
Mads Kiilerich <mads@kiilerich.com>
parents: 1090
diff changeset
   742
            if len(cmd) == 2 and cmd[0] == 'cd':
660262879b48 tests: make .t tests stop immediately if a cd fails
Mads Kiilerich <mads@kiilerich.com>
parents: 1090
diff changeset
   743
                l = '  $ cd %s || exit 1\n' % cmd[1]
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   744
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   745
        elif l.startswith('  > '): # continuations
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   746
            after.setdefault(prepos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   747
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   748
        elif l.startswith('  '): # results
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   749
            # queue up a list of expected results
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   750
            expected.setdefault(pos, []).append(l[2:])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   751
        else:
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   752
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   753
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   754
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   755
            # non-command/result - queue up for merged output
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   756
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   757
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   758
    if inpython:
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   759
        script.append("EOF\n")
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   760
    if skipping is not None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   761
        after.setdefault(pos, []).append('  !!! missing #endif\n')
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   762
    addsalt(n + 1, False)
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   763
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   764
    # Write out the script and execute it
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   765
    fd, name = tempfile.mkstemp(suffix='hg-tst')
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   766
    try:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   767
        for l in script:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   768
            os.write(fd, l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   769
        os.close(fd)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   770
1018
4d2cc32c6d97 run-tests: don't quote command names - that do apparently not work with msys
Mads Kiilerich <mads@kiilerich.com>
parents: 1017
diff changeset
   771
        cmd = '%s "%s"' % (options.shell, name)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   772
        vlog("# Running", cmd)
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   773
        exitcode, output = run(cmd, wd, options, replacements, env)
823
ab2ba4e79bed tests: show skip reason instead of "irrelevant" with unified tests, too
Thomas Arendsen Hein <thomas@intevation.de>
parents: 822
diff changeset
   774
        # do not merge output if skipped, return hghave message instead
862
c333552ec003 run-tests: fix --debug for .t tests
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 860
diff changeset
   775
        # similarly, with --debug, output is None
c333552ec003 run-tests: fix --debug for .t tests
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 860
diff changeset
   776
        if exitcode == SKIPPED_STATUS or output is None:
823
ab2ba4e79bed tests: show skip reason instead of "irrelevant" with unified tests, too
Thomas Arendsen Hein <thomas@intevation.de>
parents: 822
diff changeset
   777
            return exitcode, output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   778
    finally:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   779
        os.remove(name)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   780
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   781
    # Merge the script output back into a unified test
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   782
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   783
    pos = -1
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   784
    postout = []
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   785
    ret = 0
1135
7c026ccf4e1a run-tests: drop unused enumerate
Mads Kiilerich <mads@kiilerich.com>
parents: 1131
diff changeset
   786
    for l in output:
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   787
        lout, lcmd = l, None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   788
        if salt in l:
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   789
            lout, lcmd = l.split(salt, 1)
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   790
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   791
        if lout:
1138
bb419c4bfdd9 run-tests: use more explicit criteria for detecting no-eol
Mads Kiilerich <mads@kiilerich.com>
parents: 1135
diff changeset
   792
            if not lout.endswith('\n'):
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   793
                lout += ' (no-eol)\n'
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   794
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   795
            # find the expected output at the current position
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   796
            el = None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   797
            if pos in expected and expected[pos]:
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   798
                el = expected[pos].pop(0)
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   799
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   800
            if linematch(el, lout):
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   801
                postout.append("  " + el)
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   802
            else:
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   803
                if needescape(lout):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   804
                    lout = stringescape(lout.rstrip('\n')) + " (esc)\n"
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   805
                postout.append("  " + lout) # let diff deal with it
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   806
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   807
        if lcmd:
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   808
            # add on last return code
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   809
            ret = int(lcmd.split()[1])
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   810
            if ret != 0:
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   811
                postout.append("  [%s]\n" % ret)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   812
            if pos in after:
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   813
                # merge in non-active test bits
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   814
                postout += after.pop(pos)
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   815
            pos = int(lcmd.split()[0])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   816
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   817
    if pos in after:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   818
        postout += after.pop(pos)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   819
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   820
    return exitcode, postout
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   821
878
e1a93489159d run-tests: only call WIFEXITED on systems it exists
Simon Heimberg <simohe@besonet.ch>
parents: 877
diff changeset
   822
wifexited = getattr(os, "WIFEXITED", lambda x: False)
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   823
def run(cmd, wd, options, replacements, env):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   824
    """Run command in a sub-process, capturing the output (stdout and stderr).
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   825
    Return a tuple (exitcode, output).  output is None in debug mode."""
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   826
    # TODO: Use subprocess.Popen if we're running on Python 2.4
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   827
    if options.debug:
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   828
        proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   829
        ret = proc.wait()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   830
        return (ret, None)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   831
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   832
    proc = Popen4(cmd, wd, options.timeout, env)
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   833
    def cleanup():
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   834
        terminate(proc)
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   835
        ret = proc.wait()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   836
        if ret == 0:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   837
            ret = signal.SIGTERM << 8
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   838
        killdaemons(env['DAEMON_PIDS'])
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   839
        return ret
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   840
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   841
    output = ''
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   842
    proc.tochild.close()
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   843
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   844
    try:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   845
        output = proc.fromchild.read()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   846
    except KeyboardInterrupt:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   847
        vlog('# Handling keyboard interrupt')
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   848
        cleanup()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   849
        raise
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   850
1281
3dc7d29a42e9 run-tests: lock popen wait/poll
Brendan Cully <brendan@kublai.com>
parents: 1280
diff changeset
   851
    ret = proc.wait()
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   852
    if wifexited(ret):
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   853
        ret = os.WEXITSTATUS(ret)
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   854
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   855
    if proc.timeout:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   856
        ret = 'timeout'
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   857
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   858
    if ret:
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   859
        killdaemons(env['DAEMON_PIDS'])
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   860
1251
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   861
    if abort:
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   862
        raise KeyboardInterrupt()
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   863
826
ac9b63e01e2a tests: replace test tmp directory with $TESTTMP in test output
Mads Kiilerich <mads@kiilerich.com>
parents: 824
diff changeset
   864
    for s, r in replacements:
852
fb1e8925292d run-tests: use regex when searching for $HGPORT in test output
Martin Geisler <mg@aragost.com>
parents: 844
diff changeset
   865
        output = re.sub(s, r, output)
1139
cdabdd17f980 run-tests: allow test output lines to be terminated with \r in addition to \n
Mads Kiilerich <mads@kiilerich.com>
parents: 1138
diff changeset
   866
    return ret, output.splitlines(True)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   867
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   868
def runone(options, test, count):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   869
    '''returns a result element: (code, test, msg)'''
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   870
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   871
    def skip(msg):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   872
        if options.verbose:
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   873
            log("\nSkipping %s: %s" % (testpath, msg))
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   874
        return 's', test, msg
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   875
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   876
    def fail(msg, ret):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   877
        if not options.nodiff:
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   878
            log("\nERROR: %s %s" % (testpath, msg))
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   879
        if (not ret and options.interactive
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   880
            and os.path.exists(testpath + ".err")):
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   881
            iolock.acquire()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   882
            print "Accept this change? [n] ",
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   883
            answer = sys.stdin.readline().strip()
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   884
            iolock.release()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   885
            if answer.lower() in "y yes".split():
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   886
                if test.endswith(".t"):
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   887
                    rename(testpath + ".err", testpath)
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   888
                else:
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   889
                    rename(testpath + ".err", testpath + ".out")
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
   890
                return '.', test, ''
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
   891
        return '!', test, msg
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   892
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   893
    def success():
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
   894
        return '.', test, ''
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   895
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   896
    def ignore(msg):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   897
        return 'i', test, msg
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   898
1232
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   899
    def describe(ret):
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   900
        if ret < 0:
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   901
            return 'killed by signal %d' % -ret
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   902
        return 'returned error code %d' % ret
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   903
1233
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   904
    testpath = os.path.join(TESTDIR, test)
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   905
    err = os.path.join(TESTDIR, test + ".err")
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   906
    lctest = test.lower()
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   907
1234
750a0ed6f380 run-tests: fix a path existence check
Matt Mackall <mpm@selenic.com>
parents: 1233
diff changeset
   908
    if not os.path.exists(testpath):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   909
            return skip("doesn't exist")
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   910
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   911
    if not (options.whitelisted and test in options.whitelisted):
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   912
        if options.blacklist and test in options.blacklist:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   913
            return skip("blacklisted")
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   914
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   915
        if options.retest and not os.path.exists(test + ".err"):
1272
4a224ed7e923 run-tests: ignoring tests works again
simon@laptop-tosh
parents: 1270
diff changeset
   916
            return ignore("not retesting")
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   917
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   918
        if options.keywords:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   919
            fp = open(test)
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   920
            t = fp.read().lower() + test.lower()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   921
            fp.close()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   922
            for k in options.keywords.lower().split():
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   923
                if k in t:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   924
                    break
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   925
                else:
1272
4a224ed7e923 run-tests: ignoring tests works again
simon@laptop-tosh
parents: 1270
diff changeset
   926
                    return ignore("doesn't match keyword")
905
66b8706b3112 run-tests: move keyword checking into runone
Matt Mackall <mpm@selenic.com>
parents: 904
diff changeset
   927
1290
d56f50372ba5 run-tests: only check the common criteria once per test
Simon Heimberg <simohe@besonet.ch>
parents: 1289
diff changeset
   928
    if not lctest.startswith("test-"):
d56f50372ba5 run-tests: only check the common criteria once per test
Simon Heimberg <simohe@besonet.ch>
parents: 1289
diff changeset
   929
        return skip("not a test file")
1227
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   930
    for ext, func, out in testtypes:
1290
d56f50372ba5 run-tests: only check the common criteria once per test
Simon Heimberg <simohe@besonet.ch>
parents: 1289
diff changeset
   931
        if lctest.endswith(ext):
1227
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   932
            runner = func
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   933
            ref = os.path.join(TESTDIR, test + out)
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   934
            break
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   935
    else:
1152
9a4ed3acf89e run-tests: remove dead code for supporting old test scripts
Mads Kiilerich <mads@kiilerich.com>
parents: 1151
diff changeset
   936
        return skip("unknown test type")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   937
1235
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   938
    vlog("# Test", test)
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   939
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   940
    if os.path.exists(err):
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   941
        os.remove(err)       # Remove any previous output files
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   942
693
8428f3bda904 run-tests.py: skipped tests shouldn't change working directory
Mads Kiilerich <mads@kiilerich.com>
parents: 692
diff changeset
   943
    # Make a tmp subdirectory to work in
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   944
    threadtmp = os.path.join(HGTMP, "child%d" % count)
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   945
    testtmp = os.path.join(threadtmp, os.path.basename(test))
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   946
    os.mkdir(threadtmp)
1231
c6a4dd8d18a9 run-tests: regroup temp dir creation
Matt Mackall <mpm@selenic.com>
parents: 1230
diff changeset
   947
    os.mkdir(testtmp)
895
1a9cd0b534a0 tests: set HOME to the test temp dir (issue2707)
Idan Kamara <idankk86@gmail.com>
parents: 882
diff changeset
   948
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   949
    port = options.port + count * 3
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   950
    replacements = [
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   951
        (r':%s\b' % port, ':$HGPORT'),
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   952
        (r':%s\b' % (port + 1), ':$HGPORT1'),
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   953
        (r':%s\b' % (port + 2), ':$HGPORT2'),
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   954
        ]
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   955
    if os.name == 'nt':
1019
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   956
        replacements.append(
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   957
            (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   958
                     c in '/\\' and r'[/\\]' or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   959
                     c.isdigit() and c or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   960
                     '\\' + c
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   961
                     for c in testtmp), '$TESTTMP'))
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   962
    else:
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   963
        replacements.append((re.escape(testtmp), '$TESTTMP'))
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   964
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   965
    env = createenv(options, testtmp, threadtmp, port)
1246
e6ba976e152c run-tests: move HGRCPATH to env
Matt Mackall <mpm@selenic.com>
parents: 1245
diff changeset
   966
    createhgrc(env['HGRCPATH'], options)
e6ba976e152c run-tests: move HGRCPATH to env
Matt Mackall <mpm@selenic.com>
parents: 1245
diff changeset
   967
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   968
    starttime = time.time()
1266
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   969
    try:
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   970
        ret, out = runner(testpath, testtmp, options, replacements, env)
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   971
    except KeyboardInterrupt:
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   972
        endtime = time.time()
1270
79e0df6ffaad run-tests: simplify interrupted message
Matt Mackall <mpm@selenic.com>
parents: 1269
diff changeset
   973
        log('INTERRUPTED: %s (after %d seconds)' % (test, endtime - starttime))
1266
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   974
        raise
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   975
    endtime = time.time()
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   976
    times.append((test, endtime - starttime))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   977
    vlog("# Ret was:", ret)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   978
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   979
    killdaemons(env['DAEMON_PIDS'])
1173
d5da1c5cf1f5 tests: kill daemons early, making breaking at "Accept" prompt safe
Mads Kiilerich <madski@unity3d.com>
parents: 1172
diff changeset
   980
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   981
    skipped = (ret == SKIPPED_STATUS)
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   982
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   983
    # If we're not in --debug mode and reference output file exists,
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   984
    # check test output against it.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   985
    if options.debug:
866
d51c3fd4e34a code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 862
diff changeset
   986
        refout = None                   # to match "out is None"
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   987
    elif os.path.exists(ref):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   988
        f = open(ref, "r")
1139
cdabdd17f980 run-tests: allow test output lines to be terminated with \r in addition to \n
Mads Kiilerich <mads@kiilerich.com>
parents: 1138
diff changeset
   989
        refout = f.read().splitlines(True)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   990
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   991
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   992
        refout = []
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   993
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   994
    if (ret != 0 or out != refout) and not skipped and not options.debug:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   995
        # Save errors to a file for diagnosis
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   996
        f = open(err, "wb")
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   997
        for line in out:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   998
            f.write(line)
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   999
        f.close()
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1000
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1001
    if skipped:
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1002
        if out is None:                 # debug mode: nothing to parse
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1003
            missing = ['unknown']
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1004
            failed = None
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1005
        else:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1006
            missing, failed = parsehghaveoutput(out)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1007
        if not missing:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1008
            missing = ['irrelevant']
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1009
        if failed:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1010
            result = fail("hghave failed checking for %s" % failed[-1], ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1011
            skipped = False
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1012
        else:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1013
            result = skip(missing[-1])
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
  1014
    elif ret == 'timeout':
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1015
        result = fail("timed out", ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1016
    elif out != refout:
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1017
        if not options.nodiff:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1018
            iolock.acquire()
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1019
            if options.view:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1020
                os.system("%s %s %s" % (options.view, ref, err))
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1021
            else:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1022
                showdiff(refout, out, ref, err)
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1023
            iolock.release()
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1024
        if ret:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1025
            result = fail("output changed and " + describe(ret), ret)
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1026
        else:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1027
            result = fail("output changed", ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1028
    elif ret:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1029
        result = fail(describe(ret), ret)
921
abb2a67ce631 run-tests: don't count test as succeeded if it failed
Idan Kamara <idankk86@gmail.com>
parents: 919
diff changeset
  1030
    else:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1031
        result = success()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1032
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1033
    if not options.verbose:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1034
        iolock.acquire()
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1035
        sys.stdout.write(result[0])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1036
        sys.stdout.flush()
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1037
        iolock.release()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1038
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1039
    if not options.keep_tmpdir:
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
  1040
        shutil.rmtree(threadtmp, True)
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1041
    return result
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1042
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1043
_hgpath = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1044
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1045
def _gethgpath():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1046
    """Return the path to the mercurial package that is actually found by
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1047
    the current Python interpreter."""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1048
    global _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1049
    if _hgpath is not None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1050
        return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1051
1293
6e9bfd51bc6f run-tests: find mercurial path with syntax valid on both py2 and py3
Augie Fackler <raf@durin42.com>
parents: 1292
diff changeset
  1052
    cmd = '%s -c "import mercurial; print (mercurial.__path__[0])"'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1053
    pipe = os.popen(cmd % PYTHON)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1054
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1055
        _hgpath = pipe.read().strip()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1056
    finally:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1057
        pipe.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1058
    return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1059
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1060
def _checkhglib(verb):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1061
    """Ensure that the 'mercurial' package imported by python is
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1062
    the one we expect it to be.  If not, print a warning to stderr."""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1063
    expecthg = os.path.join(PYTHONDIR, 'mercurial')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1064
    actualhg = _gethgpath()
934
cf241f12e977 run-tests: compare absolute paths in _checkhglib
Idan Kamara <idankk86@gmail.com>
parents: 932
diff changeset
  1065
    if os.path.abspath(actualhg) != os.path.abspath(expecthg):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1066
        sys.stderr.write('warning: %s with unexpected mercurial lib: %s\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1067
                         '         (expected %s)\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1068
                         % (verb, actualhg, expecthg))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1069
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1070
results = {'.':[], '!':[], 's':[], 'i':[]}
1159
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
  1071
times = []
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1072
iolock = threading.Lock()
1251
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
  1073
abort = False
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1074
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1075
def scheduletests(options, tests):
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1076
    jobs = options.jobs
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1077
    done = queue.Queue()
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1078
    running = 0
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1079
    count = 0
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1080
    global abort
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1081
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1082
    def job(test, count):
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1083
        try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1084
            done.put(runone(options, test, count))
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1085
        except KeyboardInterrupt:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1086
            pass
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1087
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1088
    try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1089
        while tests or running:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1090
            if not done.empty() or running == jobs or not tests:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1091
                try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1092
                    code, test, msg = done.get(True, 1)
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1093
                    results[code].append((test, msg))
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1094
                    if options.first and code not in '.si':
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1095
                        break
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1096
                except queue.Empty:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1097
                    continue
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1098
                running -= 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1099
            if tests and not running == jobs:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1100
                test = tests.pop(0)
1261
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
  1101
                if options.loop:
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
  1102
                    tests.append(test)
1273
4598906608cf run-tests: call Threads constructor with keyword arguments
simon@laptop-tosh
parents: 1272
diff changeset
  1103
                t = threading.Thread(target=job, args=(test, count))
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1104
                t.start()
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1105
                running += 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1106
                count += 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1107
    except KeyboardInterrupt:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1108
        abort = True
909
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1109
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1110
def runtests(options, tests):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1111
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1112
        if INST:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1113
            installhg(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1114
            _checkhglib("Testing")
1168
96a0960a7909 run-tests: use correct python when run with --local
Bryan O'Sullivan <bryano@fb.com>
parents: 1166
diff changeset
  1115
        else:
96a0960a7909 run-tests: use correct python when run with --local
Bryan O'Sullivan <bryano@fb.com>
parents: 1166
diff changeset
  1116
            usecorrectpython()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1117
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1118
        if options.restart:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1119
            orig = list(tests)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1120
            while tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1121
                if os.path.exists(tests[0] + ".err"):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1122
                    break
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1123
                tests.pop(0)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1124
            if not tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1125
                print "running all tests"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1126
                tests = orig
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1127
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1128
        scheduletests(options, tests)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1129
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1130
        failed = len(results['!'])
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1131
        tested = len(results['.']) + failed
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1132
        skipped = len(results['s'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1133
        ignored = len(results['i'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1134
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1135
        print
1263
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1136
        if not options.noskips:
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1137
            for s in results['s']:
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1138
                print "Skipped %s: %s" % s
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1139
        for s in results['!']:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1140
            print "Failed %s: %s" % s
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1141
        _checkhglib("Tested")
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1142
        print "# Ran %d tests, %d skipped, %d failed." % (
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1143
            tested, skipped + ignored, failed)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1144
        if options.time:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1145
            outputtimes(options)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1146
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1147
        if options.anycoverage:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1148
            outputcoverage(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1149
    except KeyboardInterrupt:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1150
        failed = True
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1151
        print "\ninterrupted!"
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1152
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1153
    if failed:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1154
        sys.exit(1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1155
1227
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1156
testtypes = [('.py', pytest, '.out'),
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1157
             ('.t', tsttest, '')]
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1158
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1159
def main():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1160
    (options, args) = parseargs()
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1161
    os.umask(022)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1162
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1163
    checktools()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1164
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1165
    if len(args) == 0:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1166
        args = [t for t in os.listdir(".")
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1167
                if t.startswith("test-")
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1168
                and (t.endswith(".py") or t.endswith(".t"))]
833
a9c6ada32647 run-tests.py: do not install hg when the tests do no exist
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 829
diff changeset
  1169
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
  1170
    tests = args
833
a9c6ada32647 run-tests.py: do not install hg when the tests do no exist
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 829
diff changeset
  1171
1221
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
  1172
    if options.random:
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
  1173
        random.shuffle(tests)
1255
ac0cc929e982 run-tests: schedule largest tests first
Matt Mackall <mpm@selenic.com>
parents: 1254
diff changeset
  1174
    else:
1259
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1175
        # keywords for slow tests
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1176
        slow = 'svn gendoc check-code-hg'.split()
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1177
        def sortkey(f):
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1178
            # run largest tests first, as they tend to take the longest
1274
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1179
            try:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1180
                val = -os.stat(f).st_size
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1181
            except OSError, e:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1182
                if e.errno != errno.ENOENT:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1183
                    raise
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1184
                return -1e9 # file does not exist, tell early
1259
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1185
            for kw in slow:
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1186
                if kw in f:
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1187
                    val *= 10
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1188
            return val
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1189
        tests.sort(key=sortkey)
1221
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
  1190
1212
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1191
    if 'PYTHONHASHSEED' not in os.environ:
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1192
        # use a random python hash seed all the time
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1193
        # we do the randomness ourself to know what seed is used
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1194
        os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32))
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1195
        print 'python hash seed:', os.environ['PYTHONHASHSEED']
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1196
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1197
    global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
1090
e7e4ca624772 tests/run-tests: avoid C:/ in arguments
Adrian Buehlmann <adrian@cadifra.com>
parents: 1088
diff changeset
  1198
    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1199
    if options.tmpdir:
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1200
        options.keep_tmpdir = True
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1201
        tmpdir = options.tmpdir
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1202
        if os.path.exists(tmpdir):
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1203
            # Meaning of tmpdir has changed since 1.3: we used to create
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1204
            # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1205
            # tmpdir already exists.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1206
            sys.exit("error: temp dir %r already exists" % tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1207
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1208
            # Automatically removing tmpdir sounds convenient, but could
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1209
            # really annoy anyone in the habit of using "--tmpdir=/tmp"
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1210
            # or "--tmpdir=$HOME".
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1211
            #vlog("# Removing temp dir", tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1212
            #shutil.rmtree(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1213
        os.makedirs(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1214
    else:
1088
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1215
        d = None
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1216
        if os.name == 'nt':
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1217
            # without this, we get the default temp dir location, but
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1218
            # in all lowercase, which causes troubles with paths (issue3490)
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1219
            d = os.getenv('TMP')
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1220
        tmpdir = tempfile.mkdtemp('', 'hgtests.', d)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1221
    HGTMP = os.environ['HGTMP'] = os.path.realpath(tmpdir)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1222
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1223
    if options.with_hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1224
        INST = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1225
        BINDIR = os.path.dirname(os.path.realpath(options.with_hg))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1226
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1227
        # This looks redundant with how Python initializes sys.path from
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1228
        # the location of the script being executed.  Needed because the
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1229
        # "hg" specified by --with-hg is not the only Python script
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1230
        # executed in the test suite that needs to import 'mercurial'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1231
        # ... which means it's not really redundant at all.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1232
        PYTHONDIR = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1233
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1234
        INST = os.path.join(HGTMP, "install")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1235
        BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1236
        PYTHONDIR = os.path.join(INST, "lib", "python")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1237
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1238
    os.environ["BINDIR"] = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1239
    os.environ["PYTHON"] = PYTHON
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1240
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1241
    path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1242
    os.environ["PATH"] = os.pathsep.join(path)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1243
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1244
    # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1245
    # can run .../tests/run-tests.py test-foo where test-foo
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1246
    # adds an extension to HGRC
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1247
    pypath = [PYTHONDIR, TESTDIR]
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1248
    # We have to augment PYTHONPATH, rather than simply replacing
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1249
    # it, in case external libraries are only available via current
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1250
    # PYTHONPATH.  (In particular, the Subversion bindings on OS X
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1251
    # are in /opt/subversion.)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1252
    oldpypath = os.environ.get(IMPL_PATH)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1253
    if oldpypath:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1254
        pypath.append(oldpypath)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1255
    os.environ[IMPL_PATH] = os.pathsep.join(pypath)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1256
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1257
    COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1258
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1259
    vlog("# Using TESTDIR", TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1260
    vlog("# Using HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1261
    vlog("# Using PATH", os.environ["PATH"])
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
  1262
    vlog("# Using", IMPL_PATH, os.environ[IMPL_PATH])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1263
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1264
    try:
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1265
        runtests(options, tests)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1266
    finally:
1059
1745fd2dd308 tests: shorten post-test sleeps
Matt Mackall <mpm@selenic.com>
parents: 1046
diff changeset
  1267
        time.sleep(.1)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1268
        cleanup(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1269
877
c2ca6e172fd8 run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 866
diff changeset
  1270
if __name__ == '__main__':
c2ca6e172fd8 run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 866
diff changeset
  1271
    main()