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