tests/run-tests.py
author A. S. Budden <abudden@gmail.com>
Fri, 30 Mar 2012 22:08:46 +0100
branchstable
changeset 1057 66d2754c6f30
parent 1046 2890e1f3d8e4
child 1059 1745fd2dd308
permissions -rwxr-xr-x
record: allow splitting of hunks by manually editing patches It is possible that unrelated changes in a file are on sequential lines. The current record extension does not allow these to be committed independently. An example use case for this is in software development for deeply embedded real-time systems. In these environments, it is not always possible to use a debugger (due to time-constraints) and hence inline UART-based printing is often used. When fixing a bug in a module, it is often convenient to add a large number of 'printf's (linked to the UART via a custom fputc) to the module in order to work out what is going wrong. printf is a very slow function (and also variadic so somewhat frowned upon by the MISRA standard) and hence it is highly undesirable to commit these lines to the repository. If only a partial fix is implemented, however, it is desirable to commit the fix without deleting all of the printf lines. This is also simplifies removal of the printf lines as once the final fix is committed, 'hg revert' does the rest. It is likely that the printf lines will be very near the actual fix, so being able to split the hunk is very useful in this case. There were two alternatives I considered for the user interface. One was to manually edit the patch, the other to allow a hunk to be split into individual lines for consideration. The latter option would require a significant refactor of the record module and is less flexible. While the former is potentially more complicated to use, this is a feature that is likely to only be used in certain exceptional cases (such as the use case proposed above) and hence I felt that the complexity would not be a considerable issue. I've also written a follow-up patch that refactors the 'prompt' code to base everything on the choices variable. This tidies up and clarifies the code a bit (removes constructs like 'if ret == 7' and removes the 'e' option from the file scope options as it's not relevant there. It's not really a necessity, so I've excluded it from this submission for now, but I can send it separately if there's a desire and it's on bitbucket (see below) in the meantime. Possible future improvements include: * Tidying up the 'prompt' code to base everything on the choices variable. This would allow entries to be removed from the prompt as currently 'e' is offered even for entire file patches, which is currently unsupported. * Allowing the entire file (or even multi-file) patch to be edited manually: this would require quite a large refactor without much benefit, so I decided to exclude it from the initial submission. * Allow the option to retry if a patch fails to apply (this is what Git does). This would require quite a bit of refactoring given the current 'hg record' implementation, so it's debatable whether it's worth it. Output is similar to existing record user interface except that an additional option ('e') exists to allow manual editing of the patch. This opens the user's configured editor with the patch. A comment is added to the bottom of the patch explaining what to do (based on Git's one). A large proportion of the changeset is test-case changes to update the options reported by record (Ynesfdaq? instead of Ynsfdaq?). Functional changes are in record.py and there are some new test cases in test-record.t. [ 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
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
    55
import re
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
    56
import threading
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    57
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    58
processlock = threading.Lock()
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    59
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    60
closefds = os.name == 'posix'
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    61
def Popen4(cmd, wd, timeout):
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
    62
    processlock.acquire()
947
23f0eeb598b5 run-tests: replace chdir() with Popen cwd option
Patrick Mezard <pmezard@gmail.com>
parents: 946
diff changeset
    63
    p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd,
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    64
                         close_fds=closefds,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    65
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    66
                         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
    67
    processlock.release()
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
    p.fromchild = p.stdout
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    70
    p.tochild = p.stdin
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    71
    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
    72
944
37aff8ccb33e run-tests: ignore timeout when Popen.terminate is unavailable
Patrick Mezard <pmezard@gmail.com>
parents: 943
diff changeset
    73
    p.timeout = False
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    74
    if timeout:
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    75
        def t():
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    76
            start = time.time()
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    77
            while time.time() - start < timeout and p.returncode is None:
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    78
                time.sleep(1)
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    79
            p.timeout = True
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    80
            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
    81
                terminate(p)
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
    82
        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
    83
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    84
    return p
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    85
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    86
# 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
    87
SKIPPED_STATUS = 80
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    88
SKIPPED_PREFIX = 'skipped: '
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    89
FAILED_PREFIX  = 'hghave check failed: '
1016
b4ca7adb4bf1 run-tests: convert windows paths to unix
Mads Kiilerich <mads@kiilerich.com>
parents: 1015
diff changeset
    90
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
    91
IMPL_PATH = 'PYTHONPATH'
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
    92
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
    93
    IMPL_PATH = 'JYTHONPATH'
562
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
requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    96
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    97
defaults = {
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    98
    'jobs': ('HGTEST_JOBS', 1),
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
    99
    'timeout': ('HGTEST_TIMEOUT', 180),
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   100
    '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
   101
    'shell': ('HGTEST_SHELL', 'sh'),
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   102
}
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   103
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   104
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
   105
    entries = dict()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   106
    for filename in files:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   107
        try:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   108
            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
   109
            f = open(path, "r")
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   110
        except IOError, err:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   111
            if err.errno != errno.ENOENT:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   112
                raise
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   113
            if warn:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   114
                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
   115
            continue
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   116
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   117
        for line in f.readlines():
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   118
            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
   119
            if line:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   120
                entries[line] = filename
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   121
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   122
        f.close()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   123
    return entries
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   124
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   125
def parseargs():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   126
    parser = optparse.OptionParser("%prog [options] [tests]")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   127
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   128
    # keep these sorted
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   129
    parser.add_option("--blacklist", action="append",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   130
        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
   131
    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
   132
        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
   133
    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
   134
        help="output files annotated with coverage")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   135
    parser.add_option("--child", type="int",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   136
        help="run as child process, summary to given fd")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   137
    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
   138
        help="print a test coverage report")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   139
    parser.add_option("-d", "--debug", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   140
        help="debug mode: write output of test scripts to console"
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   141
             " 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
   142
    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
   143
        help="exit on the first test failure")
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   144
    parser.add_option("-H", "--htmlcov", action="store_true",
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   145
        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
   146
    parser.add_option("--inotify", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   147
        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
   148
    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
   149
        help="prompt to accept changed output")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   150
    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
   151
        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
   152
             " (default: $%s or %d)" % defaults['jobs'])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   153
    parser.add_option("--keep-tmpdir", action="store_true",
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   154
        help="keep temporary directory after running tests")
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   155
    parser.add_option("-k", "--keywords",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   156
        help="run tests matching keywords")
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   157
    parser.add_option("-l", "--local", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   158
        help="shortcut for --with-hg=<testdir>/../hg")
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   159
    parser.add_option("-n", "--nodiff", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   160
        help="skip showing test changes")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   161
    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
   162
        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
   163
             " (default: $%s or %d)" % defaults['port'])
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   164
    parser.add_option("--pure", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   165
        help="use pure Python code instead of C extensions")
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   166
    parser.add_option("-R", "--restart", action="store_true",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   167
        help="restart at last error")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   168
    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
   169
        help="retest failed tests")
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   170
    parser.add_option("-S", "--noskips", action="store_true",
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   171
        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
   172
    parser.add_option("--shell", type="string",
eb562ea207c3 run-tests: add --shell command line flag
Martin Geisler <mg@lazybytes.net>
parents: 931
diff changeset
   173
        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
   174
    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
   175
        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
   176
             " (default: $%s or %d)" % defaults['timeout'])
740
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   177
    parser.add_option("--tmpdir", type="string",
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   178
        help="run tests in the given temporary directory"
7d3c26dea450 run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 739
diff changeset
   179
             " (implies --keep-tmpdir)")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   180
    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
   181
        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
   182
    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
   183
        help="external diff viewer")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   184
    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
   185
        metavar="HG",
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   186
        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
   187
             "temporary installation")
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   188
    parser.add_option("-3", "--py3k-warnings", action="store_true",
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   189
        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
   190
    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
   191
                      help='set the given config opt in the test hgrc')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   192
931
b56e95db7ac5 run-tests: use type of default to convert environment variable
Martin Geisler <mg@lazybytes.net>
parents: 930
diff changeset
   193
    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
   194
        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
   195
    parser.set_defaults(**defaults)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   196
    (options, args) = parser.parse_args()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   197
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   198
    # 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
   199
    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
   200
        options.pure = True
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
   201
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   202
    if options.with_hg:
1046
2890e1f3d8e4 run-tests: expand user in --with-hg
Mads Kiilerich <mads@kiilerich.com>
parents: 1045
diff changeset
   203
        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
   204
        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
   205
                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
   206
            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
   207
        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
   208
            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
   209
    if options.local:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   210
        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
   211
        hgbin = os.path.join(os.path.dirname(testdir), 'hg')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   212
        if not os.access(hgbin, os.X_OK):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   213
            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
   214
                         % hgbin)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   215
        options.with_hg = hgbin
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   216
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   217
    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
   218
    if options.anycoverage:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   219
        try:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   220
            import coverage
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   221
            covver = version.StrictVersion(coverage.__version__).version
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   222
            if covver < (3, 3):
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   223
                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
   224
        except ImportError:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   225
            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
   226
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   227
    if options.anycoverage and options.local:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   228
        # 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
   229
        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
   230
                     "is specified")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   231
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   232
    global vlog
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   233
    if options.verbose:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   234
        if options.jobs > 1 or options.child is not None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   235
            pid = "[%d]" % os.getpid()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   236
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   237
            pid = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   238
        def vlog(*msg):
918
3071ec5d085c run-tests: add iolock to vlog
Matt Mackall <mpm@selenic.com>
parents: 916
diff changeset
   239
            iolock.acquire()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   240
            if pid:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   241
                print pid,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   242
            for m in msg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   243
                print m,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   244
            print
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   245
            sys.stdout.flush()
918
3071ec5d085c run-tests: add iolock to vlog
Matt Mackall <mpm@selenic.com>
parents: 916
diff changeset
   246
            iolock.release()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   247
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   248
        vlog = lambda *msg: None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   249
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   250
    if options.tmpdir:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   251
        options.tmpdir = os.path.expanduser(options.tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   252
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   253
    if options.jobs < 1:
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   254
        parser.error('--jobs must be positive')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   255
    if options.interactive and options.jobs > 1:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   256
        print '(--interactive overrides --jobs)'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   257
        options.jobs = 1
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   258
    if options.interactive and options.debug:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   259
        parser.error("-i/--interactive and -d/--debug are incompatible")
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   260
    if options.debug:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   261
        if options.timeout != defaults['timeout']:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   262
            sys.stderr.write(
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   263
                'warning: --timeout option ignored with --debug\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   264
        options.timeout = 0
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   265
    if options.py3k_warnings:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   266
        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
   267
            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
   268
    if options.blacklist:
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   269
        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
   270
    if options.whitelist:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   271
        options.whitelisted = parselistfiles(options.whitelist, 'whitelist',
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   272
                                             warn=options.child is None)
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   273
    else:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   274
        options.whitelisted = {}
562
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
    return (options, args)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   277
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   278
def rename(src, dst):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   279
    """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
   280
    for existing destination support.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   281
    """
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   282
    shutil.copy(src, dst)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   283
    os.remove(src)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   284
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   285
def splitnewlines(text):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   286
    '''like str.splitlines, but only split on newlines.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   287
    keep line endings.'''
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   288
    i = 0
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   289
    lines = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   290
    while True:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   291
        n = text.find('\n', i)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   292
        if n == -1:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   293
            last = text[i:]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   294
            if last:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   295
                lines.append(last)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   296
            return lines
680
f10a5301d082 many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 674
diff changeset
   297
        lines.append(text[i:n + 1])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   298
        i = n + 1
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   299
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   300
def parsehghaveoutput(lines):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   301
    '''Parse hghave log lines.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   302
    Return tuple of lists (missing, failed):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   303
      * the missing/unknown features
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   304
      * 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
   305
    missing = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   306
    failed = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   307
    for line in lines:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   308
        if line.startswith(SKIPPED_PREFIX):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   309
            line = line.splitlines()[0]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   310
            missing.append(line[len(SKIPPED_PREFIX):])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   311
        elif line.startswith(FAILED_PREFIX):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   312
            line = line.splitlines()[0]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   313
            failed.append(line[len(FAILED_PREFIX):])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   314
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   315
    return missing, failed
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   316
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   317
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
   318
    print
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   319
    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
   320
        sys.stdout.write(line)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   321
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   322
def findprogram(program):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   323
    """Search PATH for a executable program"""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   324
    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
   325
        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
   326
        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
   327
            return name
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   328
    return None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   329
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   330
def checktools():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   331
    # 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
   332
    # 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
   333
    for p in requiredtools:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   334
        if os.name == 'nt':
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   335
            p += '.exe'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   336
        found = findprogram(p)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   337
        if found:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   338
            vlog("# Found prerequisite", p, "at", found)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   339
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   340
            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
   341
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   342
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
   343
    """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
   344
    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
   345
    try:
977
a50ed14997fc tests: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 975
diff changeset
   346
        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
   347
    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
   348
        pass
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   349
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   350
def killdaemons():
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   351
    # Kill off any leftover daemon processes
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   352
    try:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   353
        fp = open(DAEMON_PIDS)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   354
        for line in fp:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   355
            try:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   356
                pid = int(line)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   357
            except ValueError:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   358
                continue
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   359
            try:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   360
                os.kill(pid, 0)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   361
                vlog('# Killing daemon process %d' % pid)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   362
                os.kill(pid, signal.SIGTERM)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   363
                time.sleep(0.25)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   364
                os.kill(pid, 0)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   365
                vlog('# Daemon process %d is stuck - really killing it' % pid)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   366
                os.kill(pid, signal.SIGKILL)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   367
            except OSError, err:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   368
                if err.errno != errno.ESRCH:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   369
                    raise
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   370
        fp.close()
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   371
        os.unlink(DAEMON_PIDS)
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   372
    except IOError:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   373
        pass
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   374
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   375
def cleanup(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   376
    if not options.keep_tmpdir:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   377
        vlog("# Cleaning up HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   378
        shutil.rmtree(HGTMP, True)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   379
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   380
def usecorrectpython():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   381
    # 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
   382
    # interpreter we use or bad things will happen.
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   383
    exedir, exename = os.path.split(sys.executable)
942
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   384
    if exename in ('python', 'python.exe'):
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   385
        path = findprogram(exename)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   386
        if os.path.dirname(path) == exedir:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   387
            return
942
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   388
    else:
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   389
        exename = 'python'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   390
    vlog('# Making python executable in test path use correct Python')
942
92325072c4d4 run-tests: fix python executable detection and copy on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 936
diff changeset
   391
    mypython = os.path.join(BINDIR, exename)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   392
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   393
        os.symlink(sys.executable, mypython)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   394
    except AttributeError:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   395
        # windows fallback
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   396
        shutil.copyfile(sys.executable, mypython)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   397
        shutil.copymode(sys.executable, mypython)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   398
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   399
def installhg(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   400
    vlog("# Performing temporary installation of HG")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   401
    installerrs = os.path.join("tests", "install.err")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   402
    pure = options.pure and "--pure" or ""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   403
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   404
    # Run installer in hg root
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   405
    script = os.path.realpath(sys.argv[0])
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   406
    hgroot = os.path.dirname(os.path.dirname(script))
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   407
    os.chdir(hgroot)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   408
    nohome = '--home=""'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   409
    if os.name == 'nt':
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   410
        # The --home="" trick works only on OS where os.sep == '/'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   411
        # 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
   412
        # least on Windows for now, deal with .pydistutils.cfg bugs
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   413
        # when they happen.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   414
        nohome = ''
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   415
    cmd = ('%s setup.py %s clean --all'
822
842e2c76e64b run-tests: move build/ directory to HGTMP
Martin Geisler <mg@lazybytes.net>
parents: 802
diff changeset
   416
           ' build --build-base="%s"'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   417
           ' install --force --prefix="%s" --install-lib="%s"'
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   418
           ' --install-scripts="%s" %s >%s 2>&1'
822
842e2c76e64b run-tests: move build/ directory to HGTMP
Martin Geisler <mg@lazybytes.net>
parents: 802
diff changeset
   419
           % (sys.executable, pure, os.path.join(HGTMP, "build"),
842e2c76e64b run-tests: move build/ directory to HGTMP
Martin Geisler <mg@lazybytes.net>
parents: 802
diff changeset
   420
              INST, PYTHONDIR, BINDIR, nohome, installerrs))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   421
    vlog("# Running", cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   422
    if os.system(cmd) == 0:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   423
        if not options.verbose:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   424
            os.remove(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   425
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   426
        f = open(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   427
        for line in f:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   428
            print line,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   429
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   430
        sys.exit(1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   431
    os.chdir(TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   432
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   433
    usecorrectpython()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   434
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   435
    vlog("# Installing dummy diffstat")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   436
    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
   437
    f.write('#!' + sys.executable + '\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   438
            'import sys\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   439
            'files = 0\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   440
            'for line in sys.stdin:\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   441
            '    if line.startswith("diff "):\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   442
            '        files += 1\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   443
            '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
   444
    f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   445
    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
   446
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   447
    if options.py3k_warnings and not options.anycoverage:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   448
        vlog("# Updating hg command to enable Py3k Warnings switch")
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   449
        f = open(os.path.join(BINDIR, 'hg'), 'r')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   450
        lines = [line.rstrip() for line in f]
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   451
        lines[0] += ' -3'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   452
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   453
        f = open(os.path.join(BINDIR, 'hg'), 'w')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   454
        for line in lines:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   455
            f.write(line + '\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   456
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   457
943
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   458
    hgbat = os.path.join(BINDIR, 'hg.bat')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   459
    if os.path.isfile(hgbat):
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   460
        # 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
   461
        # 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
   462
        f = open(hgbat, 'rb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   463
        data = f.read()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   464
        f.close()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   465
        if '"%~dp0..\python" "%~dp0hg" %*' in data:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   466
            data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   467
                                '"%~dp0python" "%~dp0hg" %*')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   468
            f = open(hgbat, 'wb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   469
            f.write(data)
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   470
            f.close()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   471
        else:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   472
            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
   473
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   474
    if options.anycoverage:
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   475
        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
   476
        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
   477
        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
   478
        shutil.copyfile(custom, target)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   479
        rc = os.path.join(TESTDIR, '.coveragerc')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   480
        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
   481
        os.environ['COVERAGE_PROCESS_START'] = rc
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   482
        fn = os.path.join(INST, '..', '.coverage')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   483
        os.environ['COVERAGE_FILE'] = fn
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   484
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   485
def outputcoverage(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   486
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   487
    vlog('# Producing coverage report')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   488
    os.chdir(PYTHONDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   489
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   490
    def covrun(*args):
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   491
        cmd = 'coverage %s' % ' '.join(args)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   492
        vlog('# Running: %s' % cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   493
        os.system(cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   494
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   495
    if options.child:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   496
        return
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   497
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   498
    covrun('-c')
1038
62b7a0759ee3 run-tests: use a list comprehension instead of map
Matt Mackall <mpm@selenic.com>
parents: 1037
diff changeset
   499
    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
   500
    covrun('-i', '-r', '"--omit=%s"' % omit) # report
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   501
    if options.htmlcov:
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   502
        htmldir = os.path.join(TESTDIR, 'htmlcov')
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   503
        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
   504
    if options.annotate:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   505
        adir = os.path.join(TESTDIR, 'annotated')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   506
        if not os.path.isdir(adir):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   507
            os.mkdir(adir)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   508
        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
   509
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   510
def pytest(test, wd, options, replacements):
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   511
    py3kswitch = options.py3k_warnings and ' -3' or ''
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   512
    cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   513
    vlog("# Running", cmd)
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   514
    return run(cmd, wd, options, replacements)
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   515
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   516
def shtest(test, wd, options, replacements):
1022
34ebea1c49c9 tests: use the specified shell for running old fashioned sh tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1019
diff changeset
   517
    cmd = '%s "%s"' % (options.shell, test)
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   518
    vlog("# Running", cmd)
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   519
    return run(cmd, wd, options, replacements)
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   520
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   521
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
   522
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
   523
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
   524
escapemap.update({'\\': '\\\\', '\r': r'\r'})
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   525
def escapef(m):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   526
    return escapemap[m.group(0)]
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   527
def stringescape(s):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   528
    return escapesub(escapef, s)
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   529
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   530
def rematch(el, l):
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   531
    try:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   532
        # ensure that the regex matches to the end of the string
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   533
        return re.match(el + r'\Z', l)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   534
    except re.error:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   535
        # el is an invalid regex
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   536
        return False
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   537
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   538
def globmatch(el, l):
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   539
    # 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
   540
    # matches \ on windows. Escaping of these caracters is supported.
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   541
    i, n = 0, len(el)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   542
    res = ''
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   543
    while i < n:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   544
        c = el[i]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   545
        i += 1
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   546
        if c == '\\' and el[i] in '*?\\/':
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   547
            res += el[i - 1:i + 1]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   548
            i += 1
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   549
        elif c == '*':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   550
            res += '.*'
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   551
        elif c == '?':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   552
            res += '.'
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   553
        elif c == '/' and os.name == 'nt':
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   554
            res += '[/\\\\]'
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   555
        else:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   556
            res += re.escape(c)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   557
    return rematch(res, l)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   558
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   559
def linematch(el, l):
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   560
    if el == l: # perfect match (fast)
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   561
        return True
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   562
    if (el and
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   563
        (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', l) or
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   564
         el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', l) or
1009
0c737b00568d tests: make '(esc)' matching in run-tests.py work as intended
Mads Kiilerich <mads@kiilerich.com>
parents: 1005
diff changeset
   565
         el.endswith(" (esc)\n") and
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   566
             (el[:-7].decode('string-escape') + '\n' == l or
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   567
              el[:-7].decode('string-escape').replace('\r', '') +
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   568
                  '\n' == l and os.name == 'nt'))):
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   569
        return True
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   570
    return False
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   571
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   572
def tsttest(test, wd, options, replacements):
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   573
    # 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
   574
    # 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
   575
    # line number and the last return code
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   576
    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
   577
    def addsalt(line, inpython):
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   578
        if inpython:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   579
            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
   580
        else:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   581
            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
   582
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   583
    # 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
   584
    # 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
   585
    # 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
   586
    # 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
   587
    after = {}
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   588
    pos = prepos = -1
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   589
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   590
    # Expected shellscript output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   591
    expected = {}
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   592
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   593
    # 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
   594
    # can generate the surrounding doctest magic
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   595
    inpython = False
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   596
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   597
    f = open(test)
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   598
    t = f.readlines()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   599
    f.close()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   600
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   601
    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
   602
    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
   603
        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
   604
    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
   605
        script.append('alias pwd="pwd -W"\n')
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   606
    for n, l in enumerate(t):
856
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   607
        if not l.endswith('\n'):
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   608
            l += '\n'
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   609
        if 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
   610
            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
   611
            prepos = pos
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   612
            pos = n
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   613
            if not inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   614
                # 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
   615
                inpython = True
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   616
                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
   617
                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
   618
            addsalt(n, True)
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   619
            script.append(l[2:])
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   620
        if l.startswith('  ... '): # python inlines
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   621
            after.setdefault(prepos, []).append(l)
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   622
            script.append(l[2:])
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   623
        elif l.startswith('  $ '): # commands
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   624
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   625
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   626
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   627
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   628
            prepos = pos
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   629
            pos = n
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   630
            addsalt(n, False)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   631
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   632
        elif l.startswith('  > '): # continuations
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   633
            after.setdefault(prepos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   634
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   635
        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
   636
            # 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
   637
            expected.setdefault(pos, []).append(l[2:])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   638
        else:
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   639
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   640
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   641
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   642
            # non-command/result - queue up for merged output
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   643
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   644
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   645
    if inpython:
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   646
        script.append("EOF\n")
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   647
    addsalt(n + 1, False)
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   648
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   649
    # Write out the script and execute it
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   650
    fd, name = tempfile.mkstemp(suffix='hg-tst')
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   651
    try:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   652
        for l in script:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   653
            os.write(fd, l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   654
        os.close(fd)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   655
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
   656
        cmd = '%s "%s"' % (options.shell, name)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   657
        vlog("# Running", cmd)
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   658
        exitcode, output = run(cmd, wd, options, replacements)
823
ab2ba4e79bed tests: show skip reason instead of "irrelevant" with unified tests, too
Thomas Arendsen Hein <thomas@intevation.de>
parents: 822
diff changeset
   659
        # 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
   660
        # similarly, with --debug, output is None
c333552ec003 run-tests: fix --debug for .t tests
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 860
diff changeset
   661
        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
   662
            return exitcode, output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   663
    finally:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   664
        os.remove(name)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   665
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   666
    # 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
   667
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   668
    pos = -1
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   669
    postout = []
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   670
    ret = 0
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   671
    for n, l in enumerate(output):
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   672
        lout, lcmd = l, None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   673
        if salt in l:
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   674
            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
   675
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   676
        if lout:
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   677
            if lcmd:
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   678
                # output block had no trailing newline, clean up
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   679
                lout += ' (no-eol)\n'
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   680
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   681
            # 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
   682
            el = None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   683
            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
   684
                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
   685
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   686
            if linematch(el, lout):
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   687
                postout.append("  " + el)
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   688
            else:
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   689
                if needescape(lout):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   690
                    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
   691
                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
   692
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   693
        if lcmd:
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   694
            # 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
   695
            ret = int(lcmd.split()[1])
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   696
            if ret != 0:
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   697
                postout.append("  [%s]\n" % ret)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   698
            if pos in after:
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   699
                # merge in non-active test bits
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   700
                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
   701
            pos = int(lcmd.split()[0])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   702
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   703
    if pos in after:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   704
        postout += after.pop(pos)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   705
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   706
    return exitcode, postout
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   707
878
e1a93489159d run-tests: only call WIFEXITED on systems it exists
Simon Heimberg <simohe@besonet.ch>
parents: 877
diff changeset
   708
wifexited = getattr(os, "WIFEXITED", lambda x: False)
919
1666a4a68262 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 918
diff changeset
   709
def run(cmd, wd, options, replacements):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   710
    """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
   711
    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
   712
    # 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
   713
    if options.debug:
946
b6a39effa432 run-tests: make --debug run in the temporary test directory
Patrick Mezard <pmezard@gmail.com>
parents: 945
diff changeset
   714
        proc = subprocess.Popen(cmd, shell=True, cwd=wd)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   715
        ret = proc.wait()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   716
        return (ret, None)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   717
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   718
    proc = Popen4(cmd, wd, options.timeout)
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   719
    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
   720
        terminate(proc)
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   721
        ret = proc.wait()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   722
        if ret == 0:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   723
            ret = signal.SIGTERM << 8
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   724
        killdaemons()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   725
        return ret
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   726
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   727
    output = ''
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   728
    proc.tochild.close()
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   729
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   730
    try:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   731
        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
   732
    except KeyboardInterrupt:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   733
        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
   734
        cleanup()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   735
        raise
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   736
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   737
    ret = proc.wait()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   738
    if wifexited(ret):
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   739
        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
   740
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   741
    if proc.timeout:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   742
        ret = 'timeout'
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   743
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   744
    if ret:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   745
        killdaemons()
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   746
826
ac9b63e01e2a tests: replace test tmp directory with $TESTTMP in test output
Mads Kiilerich <mads@kiilerich.com>
parents: 824
diff changeset
   747
    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
   748
        output = re.sub(s, r, output)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   749
    return ret, splitnewlines(output)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   750
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   751
def runone(options, test):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   752
    '''tristate output:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   753
    None -> skipped
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   754
    True -> passed
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   755
    False -> failed'''
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   756
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
   757
    global results, resultslock, iolock
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   758
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   759
    testpath = os.path.join(TESTDIR, test)
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   760
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   761
    def result(l, e):
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   762
        resultslock.acquire()
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   763
        results[l].append(e)
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   764
        resultslock.release()
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   765
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   766
    def skip(msg):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   767
        if not options.verbose:
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   768
            result('s', (test, msg))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   769
        else:
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   770
            iolock.acquire()
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   771
            print "\nSkipping %s: %s" % (testpath, msg)
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   772
            iolock.release()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   773
        return None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   774
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   775
    def fail(msg, ret):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   776
        if not options.nodiff:
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   777
            iolock.acquire()
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   778
            print "\nERROR: %s %s" % (testpath, msg)
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   779
            iolock.release()
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   780
        if (not ret and options.interactive
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   781
            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
   782
            iolock.acquire()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   783
            print "Accept this change? [n] ",
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   784
            answer = sys.stdin.readline().strip()
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   785
            iolock.release()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   786
            if answer.lower() in "y yes".split():
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   787
                if test.endswith(".t"):
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   788
                    rename(testpath + ".err", testpath)
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   789
                else:
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   790
                    rename(testpath + ".err", testpath + ".out")
975
98fa0fa48b7d run-tests: fix summary when accepting changes interactively
Patrick Mezard <pmezard@gmail.com>
parents: 971
diff changeset
   791
                result('p', test)
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   792
                return
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   793
        result('f', (test, msg))
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   794
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   795
    def success():
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   796
        result('p', test)
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   797
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   798
    def ignore(msg):
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
   799
        result('i', (test, msg))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   800
935
60045f152c3b run-tests: take the basepath when constructing the test temp dir
Idan Kamara <idankk86@gmail.com>
parents: 934
diff changeset
   801
    if (os.path.basename(test).startswith("test-") and '~' not in test and
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   802
        ('.' not in test or test.endswith('.py') or
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   803
         test.endswith('.bat') or test.endswith('.t'))):
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   804
        if not os.path.exists(test):
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   805
            skip("doesn't exist")
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   806
            return None
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   807
    else:
966
e6f112b6f14b run-tests: verbose log ignored test
Idan Kamara <idankk86@gmail.com>
parents: 962
diff changeset
   808
        vlog('# Test file', test, 'not supported, ignoring')
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   809
        return None # not a supported test, don't record
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
   810
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   811
    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
   812
        if options.blacklist and test in options.blacklist:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   813
            skip("blacklisted")
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   814
            return None
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   815
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   816
        if options.retest and not os.path.exists(test + ".err"):
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   817
            ignore("not retesting")
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   818
            return None
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   819
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   820
        if options.keywords:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   821
            fp = open(test)
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   822
            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
   823
            fp.close()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   824
            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
   825
                if k in t:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   826
                    break
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   827
                else:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   828
                    ignore("doesn't match keyword")
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   829
                    return None
905
66b8706b3112 run-tests: move keyword checking into runone
Matt Mackall <mpm@selenic.com>
parents: 904
diff changeset
   830
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   831
    vlog("# Test", test)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   832
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   833
    # create a fresh hgrc
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   834
    hgrc = open(HGRCPATH, 'w+')
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   835
    hgrc.write('[ui]\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   836
    hgrc.write('slash = True\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   837
    hgrc.write('[defaults]\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   838
    hgrc.write('backout = -d "0 0"\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   839
    hgrc.write('commit = -d "0 0"\n')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   840
    hgrc.write('tag = -d "0 0"\n')
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   841
    if options.inotify:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   842
        hgrc.write('[extensions]\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   843
        hgrc.write('inotify=\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   844
        hgrc.write('[inotify]\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   845
        hgrc.write('pidfile=%s\n' % DAEMON_PIDS)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   846
        hgrc.write('appendpid=True\n')
926
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   847
    if options.extra_config_opt:
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   848
        for opt in options.extra_config_opt:
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   849
            section, key = opt.split('.', 1)
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   850
            assert '=' in key, ('extra config opt %s must '
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   851
                                'have an = for assignment' % opt)
f4903069a215 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 923
diff changeset
   852
            hgrc.write('[%s]\n%s\n' % (section, key))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   853
    hgrc.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   854
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   855
    ref = os.path.join(TESTDIR, test+".out")
693
8428f3bda904 run-tests.py: skipped tests shouldn't change working directory
Mads Kiilerich <mads@kiilerich.com>
parents: 692
diff changeset
   856
    err = os.path.join(TESTDIR, test+".err")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   857
    if os.path.exists(err):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   858
        os.remove(err)       # Remove any previous output files
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   859
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   860
        tf = open(testpath)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   861
        firstline = tf.readline().rstrip()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   862
        tf.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   863
    except:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   864
        firstline = ''
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   865
    lctest = test.lower()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   866
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   867
    if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   868
        runner = pytest
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   869
    elif lctest.endswith('.t'):
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   870
        runner = tsttest
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   871
        ref = testpath
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   872
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   873
        # do not try to run non-executable programs
834
5a6898736b1a run-tests.py: remove support for .bat files
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 833
diff changeset
   874
        if not os.access(testpath, os.X_OK):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   875
            return skip("not executable")
775
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   876
        runner = shtest
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   877
693
8428f3bda904 run-tests.py: skipped tests shouldn't change working directory
Mads Kiilerich <mads@kiilerich.com>
parents: 692
diff changeset
   878
    # Make a tmp subdirectory to work in
895
1a9cd0b534a0 tests: set HOME to the test temp dir (issue2707)
Idan Kamara <idankk86@gmail.com>
parents: 882
diff changeset
   879
    testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
1016
b4ca7adb4bf1 run-tests: convert windows paths to unix
Mads Kiilerich <mads@kiilerich.com>
parents: 1015
diff changeset
   880
        os.path.join(HGTMP, os.path.basename(test)).replace('\\', '/')
895
1a9cd0b534a0 tests: set HOME to the test temp dir (issue2707)
Idan Kamara <idankk86@gmail.com>
parents: 882
diff changeset
   881
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   882
    replacements = [
852
fb1e8925292d run-tests: use regex when searching for $HGPORT in test output
Martin Geisler <mg@aragost.com>
parents: 844
diff changeset
   883
        (r':%s\b' % options.port, ':$HGPORT'),
fb1e8925292d run-tests: use regex when searching for $HGPORT in test output
Martin Geisler <mg@aragost.com>
parents: 844
diff changeset
   884
        (r':%s\b' % (options.port + 1), ':$HGPORT1'),
fb1e8925292d run-tests: use regex when searching for $HGPORT in test output
Martin Geisler <mg@aragost.com>
parents: 844
diff changeset
   885
        (r':%s\b' % (options.port + 2), ':$HGPORT2'),
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   886
        ]
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   887
    if os.name == 'nt':
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   888
        replacements.append((r'\r\n', '\n'))
1019
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   889
        replacements.append(
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   890
            (''.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
   891
                     c in '/\\' and r'[/\\]' or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   892
                     c.isdigit() and c or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   893
                     '\\' + c
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   894
                     for c in testtmp), '$TESTTMP'))
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   895
    else:
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   896
        replacements.append((re.escape(testtmp), '$TESTTMP'))
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   897
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   898
    os.mkdir(testtmp)
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   899
    ret, out = runner(testpath, testtmp, options, replacements)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   900
    vlog("# Ret was:", ret)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   901
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   902
    mark = '.'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   903
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   904
    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
   905
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   906
    # 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
   907
    # check test output against it.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   908
    if options.debug:
866
d51c3fd4e34a code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 862
diff changeset
   909
        refout = None                   # to match "out is None"
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   910
    elif os.path.exists(ref):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   911
        f = open(ref, "r")
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   912
        refout = list(splitnewlines(f.read()))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   913
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   914
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   915
        refout = []
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   916
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   917
    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
   918
        # 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
   919
        f = open(err, "wb")
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   920
        for line in out:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   921
            f.write(line)
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   922
        f.close()
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   923
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   924
    if skipped:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   925
        mark = 's'
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   926
        if out is None:                 # debug mode: nothing to parse
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   927
            missing = ['unknown']
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   928
            failed = None
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   929
        else:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   930
            missing, failed = parsehghaveoutput(out)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   931
        if not missing:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   932
            missing = ['irrelevant']
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   933
        if failed:
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   934
            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
   935
            skipped = False
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   936
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   937
            skip(missing[-1])
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   938
    elif ret == 'timeout':
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   939
        mark = 't'
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   940
        fail("timed out", ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   941
    elif out != refout:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   942
        mark = '!'
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
   943
        if not options.nodiff:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
   944
            iolock.acquire()
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   945
            if options.view:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   946
                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
   947
            else:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
   948
                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
   949
            iolock.release()
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
   950
        if ret:
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
   951
            fail("output changed and returned error code %d" % ret, ret)
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
   952
        else:
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
   953
            fail("output changed", ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   954
        ret = 1
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   955
    elif ret:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   956
        mark = '!'
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   957
        fail("returned error code %d" % ret, ret)
921
abb2a67ce631 run-tests: don't count test as succeeded if it failed
Idan Kamara <idankk86@gmail.com>
parents: 919
diff changeset
   958
    else:
abb2a67ce631 run-tests: don't count test as succeeded if it failed
Idan Kamara <idankk86@gmail.com>
parents: 919
diff changeset
   959
        success()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   960
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   961
    if not options.verbose:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
   962
        iolock.acquire()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   963
        sys.stdout.write(mark)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   964
        sys.stdout.flush()
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
   965
        iolock.release()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   966
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   967
    killdaemons()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   968
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   969
    if not options.keep_tmpdir:
826
ac9b63e01e2a tests: replace test tmp directory with $TESTTMP in test output
Mads Kiilerich <mads@kiilerich.com>
parents: 824
diff changeset
   970
        shutil.rmtree(testtmp, True)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   971
    if skipped:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   972
        return None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   973
    return ret == 0
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   974
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   975
_hgpath = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   976
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   977
def _gethgpath():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   978
    """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
   979
    the current Python interpreter."""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   980
    global _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   981
    if _hgpath is not None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   982
        return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   983
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   984
    cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   985
    pipe = os.popen(cmd % PYTHON)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   986
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   987
        _hgpath = pipe.read().strip()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   988
    finally:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   989
        pipe.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   990
    return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   991
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   992
def _checkhglib(verb):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   993
    """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
   994
    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
   995
    expecthg = os.path.join(PYTHONDIR, 'mercurial')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   996
    actualhg = _gethgpath()
934
cf241f12e977 run-tests: compare absolute paths in _checkhglib
Idan Kamara <idankk86@gmail.com>
parents: 932
diff changeset
   997
    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
   998
        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
   999
                         '         (expected %s)\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1000
                         % (verb, actualhg, expecthg))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1001
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1002
def runchildren(options, tests):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1003
    if INST:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1004
        installhg(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1005
        _checkhglib("Testing")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1006
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1007
    optcopy = dict(options.__dict__)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1008
    optcopy['jobs'] = 1
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1009
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1010
    # Because whitelist has to override keyword matches, we have to
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1011
    # actually load the whitelist in the children as well, so we allow
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1012
    # the list of whitelist files to pass through and be parsed in the
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1013
    # children, but not the dict of whitelisted tests resulting from
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1014
    # the parse, used here to override blacklisted tests.
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1015
    whitelist = optcopy['whitelisted'] or []
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1016
    del optcopy['whitelisted']
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1017
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1018
    blacklist = optcopy['blacklist'] or []
725
212432db2043 Fix --blacklist when --jobs > 1 in run_tests.py.
Ry4an Brase <ry4an-hg@ry4an.org>
parents: 724
diff changeset
  1019
    del optcopy['blacklist']
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1020
    blacklisted = []
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1021
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1022
    if optcopy['with_hg'] is None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1023
        optcopy['with_hg'] = os.path.join(BINDIR, "hg")
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
  1024
    optcopy.pop('anycoverage', None)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
  1025
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1026
    opts = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1027
    for opt, value in optcopy.iteritems():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1028
        name = '--' + opt.replace('_', '-')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1029
        if value is True:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1030
            opts.append(name)
930
730303014491 run-tests.py: correctly handle list options with parallel tasks
Augie Fackler <durin42@gmail.com>
parents: 926
diff changeset
  1031
        elif isinstance(value, list):
730303014491 run-tests.py: correctly handle list options with parallel tasks
Augie Fackler <durin42@gmail.com>
parents: 926
diff changeset
  1032
            for v in value:
730303014491 run-tests.py: correctly handle list options with parallel tasks
Augie Fackler <durin42@gmail.com>
parents: 926
diff changeset
  1033
                opts.append(name + '=' + str(v))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1034
        elif value is not None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1035
            opts.append(name + '=' + str(value))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1036
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1037
    tests.reverse()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1038
    jobs = [[] for j in xrange(options.jobs)]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1039
    while tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1040
        for job in jobs:
680
f10a5301d082 many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 674
diff changeset
  1041
            if not tests:
f10a5301d082 many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 674
diff changeset
  1042
                break
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1043
            test = tests.pop()
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
  1044
            if test not in whitelist and test in blacklist:
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1045
                blacklisted.append(test)
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1046
            else:
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1047
                job.append(test)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1048
    fps = {}
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1049
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1050
    for j, job in enumerate(jobs):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1051
        if not job:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1052
            continue
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1053
        rfd, wfd = os.pipe()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1054
        childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1055
        childtmp = os.path.join(HGTMP, 'child%d' % j)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1056
        childopts += ['--tmpdir', childtmp]
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1057
        cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1058
        vlog(' '.join(cmdline))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1059
        fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1060
        os.close(wfd)
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1061
    signal.signal(signal.SIGINT, signal.SIG_IGN)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1062
    failures = 0
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1063
    tested, skipped, failed = 0, 0, 0
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1064
    skips = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1065
    fails = []
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1066
    while fps:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1067
        pid, status = os.wait()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1068
        fp = fps.pop(pid)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1069
        l = fp.read().splitlines()
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1070
        try:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1071
            test, skip, fail = map(int, l[:3])
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1072
        except ValueError:
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1073
            test, skip, fail = 0, 0, 0
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1074
        split = -fail or len(l)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1075
        for s in l[3:split]:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1076
            skips.append(s.split(" ", 1))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1077
        for s in l[split:]:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1078
            fails.append(s.split(" ", 1))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1079
        tested += test
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1080
        skipped += skip
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1081
        failed += fail
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1082
        vlog('pid %d exited, status %d' % (pid, status))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1083
        failures |= status
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1084
    print
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1085
    skipped += len(blacklisted)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1086
    if not options.noskips:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1087
        for s in skips:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1088
            print "Skipped %s: %s" % (s[0], s[1])
956
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1089
        for s in blacklisted:
e39ab51937a2 run-tests: fix --blacklist with jobs > 1
Idan Kamara <idankk86@gmail.com>
parents: 955
diff changeset
  1090
            print "Skipped %s: blacklisted" % s
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1091
    for s in fails:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1092
        print "Failed %s: %s" % (s[0], s[1])
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1093
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1094
    _checkhglib("Tested")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1095
    print "# Ran %d tests, %d skipped, %d failed." % (
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1096
        tested, skipped, failed)
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
  1097
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
  1098
    if options.anycoverage:
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
  1099
        outputcoverage(options)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1100
    sys.exit(failures != 0)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1101
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1102
results = dict(p=[], f=[], s=[], i=[])
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1103
resultslock = threading.Lock()
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1104
iolock = threading.Lock()
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1105
909
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1106
def runqueue(options, tests, results):
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1107
    for test in tests:
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1108
        ret = runone(options, test)
909
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1109
        if options.first and ret is not None and not ret:
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1110
            break
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1111
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1112
def runtests(options, tests):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1113
    global DAEMON_PIDS, HGRCPATH
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1114
    DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1115
    HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1116
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1117
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1118
        if INST:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1119
            installhg(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1120
            _checkhglib("Testing")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1121
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1122
        if options.restart:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1123
            orig = list(tests)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1124
            while tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1125
                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
  1126
                    break
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1127
                tests.pop(0)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1128
            if not tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1129
                print "running all tests"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1130
                tests = orig
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1131
909
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1132
        runqueue(options, tests, results)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1133
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1134
        failed = len(results['f'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1135
        tested = len(results['p']) + failed
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1136
        skipped = len(results['s'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1137
        ignored = len(results['i'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1138
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1139
        if options.child:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1140
            fp = os.fdopen(options.child, 'w')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1141
            fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1142
            for s in results['s']:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1143
                fp.write("%s %s\n" % s)
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1144
            for s in results['f']:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1145
                fp.write("%s %s\n" % s)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1146
            fp.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1147
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1148
            print
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1149
            for s in results['s']:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1150
                print "Skipped %s: %s" % s
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1151
            for s in results['f']:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1152
                print "Failed %s: %s" % s
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1153
            _checkhglib("Tested")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1154
            print "# Ran %d tests, %d skipped, %d failed." % (
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1155
                tested, skipped + ignored, failed)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1156
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1157
        if options.anycoverage:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1158
            outputcoverage(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1159
    except KeyboardInterrupt:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1160
        failed = True
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1161
        print "\ninterrupted!"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1162
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1163
    if failed:
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1164
        sys.exit(1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1165
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1166
def main():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1167
    (options, args) = parseargs()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1168
    if not options.child:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1169
        os.umask(022)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1170
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1171
        checktools()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1172
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
  1173
    if len(args) == 0:
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
  1174
        args = os.listdir(".")
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
  1175
    args.sort()
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
  1176
903
92c48e9ca3a7 run-tests: move existence/name format check into runone
Matt Mackall <mpm@selenic.com>
parents: 902
diff changeset
  1177
    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
  1178
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1179
    # Reset some environment variables to well-known values so that
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1180
    # the tests produce repeatable output.
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1181
    os.environ['LANG'] = os.environ['LC_ALL'] = os.environ['LANGUAGE'] = 'C'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1182
    os.environ['TZ'] = 'GMT'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1183
    os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1184
    os.environ['CDPATH'] = ''
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1185
    os.environ['COLUMNS'] = '80'
719
ad3048630bd8 run-tests: make sure GREP_OPTIONS isn't set
Brodie Rao <brodie@bitheap.org>
parents: 718
diff changeset
  1186
    os.environ['GREP_OPTIONS'] = ''
692
5ac40b193130 run-tests.py: clears http_proxy for all tests
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 683
diff changeset
  1187
    os.environ['http_proxy'] = ''
996
dadecc4f3341 run-tests: make sure no_proxy/NO_PROXY are empty to fix test-http-proxy.t
Thomas Arendsen Hein <thomas@intevation.de>
parents: 989
diff changeset
  1188
    os.environ['no_proxy'] = ''
dadecc4f3341 run-tests: make sure no_proxy/NO_PROXY are empty to fix test-http-proxy.t
Thomas Arendsen Hein <thomas@intevation.de>
parents: 989
diff changeset
  1189
    os.environ['NO_PROXY'] = ''
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1190
724
211fa4b9803d run-tests.py: reset env variables set by hooks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 722
diff changeset
  1191
    # unset env related to hooks
211fa4b9803d run-tests.py: reset env variables set by hooks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 722
diff changeset
  1192
    for k in os.environ.keys():
211fa4b9803d run-tests.py: reset env variables set by hooks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 722
diff changeset
  1193
        if k.startswith('HG_'):
728
5df6643c39e9 run-tests.py: can't remove from os.environ on solaris
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 726
diff changeset
  1194
            # can't remove on solaris
5df6643c39e9 run-tests.py: can't remove from os.environ on solaris
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 726
diff changeset
  1195
            os.environ[k] = ''
724
211fa4b9803d run-tests.py: reset env variables set by hooks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 722
diff changeset
  1196
            del os.environ[k]
211fa4b9803d run-tests.py: reset env variables set by hooks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 722
diff changeset
  1197
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1198
    global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1199
    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1200
    if options.tmpdir:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1201
        options.keep_tmpdir = True
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1202
        tmpdir = options.tmpdir
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1203
        if os.path.exists(tmpdir):
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1204
            # 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
  1205
            # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1206
            # tmpdir already exists.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1207
            sys.exit("error: temp dir %r already exists" % tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1208
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1209
            # Automatically removing tmpdir sounds convenient, but could
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1210
            # really annoy anyone in the habit of using "--tmpdir=/tmp"
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1211
            # or "--tmpdir=$HOME".
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1212
            #vlog("# Removing temp dir", tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1213
            #shutil.rmtree(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1214
        os.makedirs(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1215
    else:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1216
        tmpdir = tempfile.mkdtemp('', 'hgtests.')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1217
    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
  1218
    DAEMON_PIDS = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1219
    HGRCPATH = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1220
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1221
    os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1222
    os.environ["HGMERGE"] = "internal:merge"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1223
    os.environ["HGUSER"]   = "test"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1224
    os.environ["HGENCODING"] = "ascii"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1225
    os.environ["HGENCODINGMODE"] = "strict"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1226
    os.environ["HGPORT"] = str(options.port)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1227
    os.environ["HGPORT1"] = str(options.port + 1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1228
    os.environ["HGPORT2"] = str(options.port + 2)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1229
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1230
    if options.with_hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1231
        INST = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1232
        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
  1233
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1234
        # 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
  1235
        # 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
  1236
        # "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
  1237
        # 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
  1238
        # ... 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
  1239
        PYTHONDIR = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1240
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1241
        INST = os.path.join(HGTMP, "install")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1242
        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
  1243
        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
  1244
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1245
    os.environ["BINDIR"] = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1246
    os.environ["PYTHON"] = PYTHON
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1247
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1248
    if not options.child:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1249
        path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1250
        os.environ["PATH"] = os.pathsep.join(path)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1251
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1252
        # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1253
        # can run .../tests/run-tests.py test-foo where test-foo
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1254
        # adds an extension to HGRC
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1255
        pypath = [PYTHONDIR, TESTDIR]
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1256
        # We have to augment PYTHONPATH, rather than simply replacing
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1257
        # it, in case external libraries are only available via current
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1258
        # PYTHONPATH.  (In particular, the Subversion bindings on OS X
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1259
        # are in /opt/subversion.)
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
  1260
        oldpypath = os.environ.get(IMPL_PATH)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1261
        if oldpypath:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1262
            pypath.append(oldpypath)
720
8008f7627b2f tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 719
diff changeset
  1263
        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
  1264
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1265
    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
  1266
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1267
    vlog("# Using TESTDIR", TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1268
    vlog("# Using HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1269
    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
  1270
    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
  1271
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1272
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1273
        if len(tests) > 1 and options.jobs > 1:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1274
            runchildren(options, tests)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1275
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1276
            runtests(options, tests)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1277
    finally:
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
  1278
        time.sleep(1)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1279
        cleanup(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1280
877
c2ca6e172fd8 run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 866
diff changeset
  1281
if __name__ == '__main__':
c2ca6e172fd8 run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 866
diff changeset
  1282
    main()