tests/run-tests.py
author Simon Heimberg <simohe@besonet.ch>
Mon, 25 Nov 2013 22:00:46 +0100
branchstable
changeset 1370 d6cab997a43e
parent 1369 1161be3ff133
permissions -rwxr-xr-x
run-tests: test result shows when a failed test could not start a server Failing to start a server happens regularly, at least on windows buildbot. Such a failure often has nothing to do with the test, but with the environment. But half the test output can change because some data is missing. Therefore this is worth an extended error message. Detect the server failure in the diff output because it is most reliable there. Checking the output only does not show if the server failure was expected. Old failure message when server start failed: Failed test-serve.t: output changed New message: Failed test-serve.t: serve failed and output changed [ 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"
1369
1161be3ff133 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 1368
diff changeset
   152
             " rather than capturing and diffing 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
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   307
    servefail = False
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   308
    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
   309
        sys.stdout.write(line)
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   310
        if not servefail and line.startswith(
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   311
                             '+  abort: child process failed to start'):
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   312
            servefail = True
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   313
    return {'servefail': servefail}
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
   314
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   315
1238
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   316
verbose = False
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   317
def vlog(*msg):
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   318
    if verbose is not False:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   319
        iolock.acquire()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   320
        if verbose:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   321
            print verbose,
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   322
        for m in msg:
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   323
            print m,
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   324
        print
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   325
        sys.stdout.flush()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   326
        iolock.release()
c2b8e0ffffc8 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 1237
diff changeset
   327
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   328
def log(*msg):
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   329
    iolock.acquire()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   330
    if verbose:
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   331
        print verbose,
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   332
    for m in msg:
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   333
        print m,
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   334
    print
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   335
    sys.stdout.flush()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   336
    iolock.release()
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   337
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   338
def findprogram(program):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   339
    """Search PATH for a executable program"""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   340
    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
   341
        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
   342
        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
   343
            return name
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   344
    return None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   345
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   346
def createhgrc(path, options):
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   347
    # create a fresh hgrc
1265
ae952fb9707f run-tests: open hgrc file only for writing
Simon Heimberg <simohe@besonet.ch>
parents: 1263
diff changeset
   348
    hgrc = open(path, 'w')
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   349
    hgrc.write('[ui]\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   350
    hgrc.write('slash = True\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   351
    hgrc.write('interactive = False\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   352
    hgrc.write('[defaults]\n')
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   353
    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
   354
    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
   355
    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
   356
    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
   357
    if options.extra_config_opt:
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   358
        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
   359
            section, key = opt.split('.', 1)
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   360
            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
   361
                                'have an = for assignment' % opt)
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   362
            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
   363
    hgrc.close()
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   364
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   365
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
   366
    env = os.environ.copy()
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   367
    env['TESTTMP'] = testtmp
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   368
    env['HOME'] = testtmp
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   369
    env["HGPORT"] = str(port)
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   370
    env["HGPORT1"] = str(port + 1)
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   371
    env["HGPORT2"] = str(port + 2)
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   372
    env["HGRCPATH"] = os.path.join(threadtmp, '.hgrc')
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   373
    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
   374
    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
   375
    env["HGMERGE"] = "internal:merge"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   376
    env["HGUSER"]   = "test"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   377
    env["HGENCODING"] = "ascii"
d0b3f7f38c72 run-tests: move more variables to env
Matt Mackall <mpm@selenic.com>
parents: 1249
diff changeset
   378
    env["HGENCODINGMODE"] = "strict"
1247
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   379
1248
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   380
    # 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
   381
    # the tests produce repeatable output.
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   382
    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
   383
    env['TZ'] = 'GMT'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   384
    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
   385
    env['COLUMNS'] = '80'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   386
    env['TERM'] = 'xterm'
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   387
1249
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   388
    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
   389
              'NO_PROXY').split():
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   390
        if k in env:
d402cca6f9b1 run-tests: simplify env deletion
Matt Mackall <mpm@selenic.com>
parents: 1248
diff changeset
   391
            del env[k]
1248
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   392
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   393
    # unset env related to hooks
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   394
    for k in env.keys():
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   395
        if k.startswith('HG_'):
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   396
            del env[k]
44c6de7459a7 run-tests: move most of remaining environment tweaks
Matt Mackall <mpm@selenic.com>
parents: 1247
diff changeset
   397
1247
7691a1e24745 run-tests: move environment creation to a separate function
Matt Mackall <mpm@selenic.com>
parents: 1246
diff changeset
   398
    return env
1230
29767671c053 run-tests: pull hgrc creation out as function
Matt Mackall <mpm@selenic.com>
parents: 1229
diff changeset
   399
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   400
def checktools():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   401
    # 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
   402
    # 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
   403
    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
   404
        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
   405
            p += '.exe'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   406
        found = findprogram(p)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   407
        if found:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   408
            vlog("# Found prerequisite", p, "at", found)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   409
        else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   410
            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
   411
970
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   412
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
   413
    """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
   414
    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
   415
    try:
977
a50ed14997fc tests: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 975
diff changeset
   416
        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
   417
    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
   418
        pass
e42946273064 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 966
diff changeset
   419
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   420
def killdaemons(pidfile):
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   421
    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
   422
                               logfn=vlog)
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   423
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   424
def cleanup(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   425
    if not options.keep_tmpdir:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   426
        vlog("# Cleaning up HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   427
        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
   428
        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
   429
            try:
d8b739c3d37a run-tests: remove files that we potentially create outside of $TMPDIR
Sean Farley <sean.michael.farley@gmail.com>
parents: 1304
diff changeset
   430
                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
   431
            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
   432
                pass
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   433
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   434
def usecorrectpython():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   435
    # 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
   436
    # 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
   437
    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
   438
    if getattr(os, 'symlink', None):
1175
62cc0851c70f run-tests: fix whitespace nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 1174
diff changeset
   439
        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
   440
             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
   441
        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
   442
        try:
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   443
            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
   444
                return
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   445
            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
   446
        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
   447
            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
   448
                raise
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   449
        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
   450
            try:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   451
                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
   452
                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
   453
            except OSError, err:
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   454
                # 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
   455
                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
   456
                    raise
1174
193946338595 run-tests: on windows, put correct python at front of PATH
Bryan O'Sullivan <bryano@fb.com>
parents: 1173
diff changeset
   457
    else:
1186
d821f658f7a3 run-tests.py: fix handling of symlink to the right python
Mads Kiilerich <mads@kiilerich.com>
parents: 1183
diff changeset
   458
        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
   459
        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
   460
             (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
   461
        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
   462
        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
   463
            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
   464
        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
   465
        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
   466
            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
   467
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   468
def installhg(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   469
    vlog("# Performing temporary installation of HG")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   470
    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
   471
    compiler = ''
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   472
    if options.compiler:
b0fa589b35b0 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 1164
diff changeset
   473
        compiler = '--compiler ' + options.compiler
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   474
    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
   475
    py3 = ''
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   476
    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
   477
        py3 = '--c2to3'
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   478
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   479
    # Run installer in hg root
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   480
    script = os.path.realpath(sys.argv[0])
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   481
    hgroot = os.path.dirname(os.path.dirname(script))
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   482
    os.chdir(hgroot)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   483
    nohome = '--home=""'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   484
    if os.name == 'nt':
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   485
        # The --home="" trick works only on OS where os.sep == '/'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   486
        # 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
   487
        # least on Windows for now, deal with .pydistutils.cfg bugs
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   488
        # when they happen.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   489
        nohome = ''
1292
aa3c5b7a290e run-tests: if run by python3, execute setup.py with --c2to3
Augie Fackler <raf@durin42.com>
parents: 1290
diff changeset
   490
    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
   491
           ' 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
   492
           ' 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
   493
           ' --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
   494
           % {'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
   495
              '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
   496
              'prefix': INST, 'libdir': PYTHONDIR, 'bindir': BINDIR,
238b6ca6d2bb run-tests: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 1350
diff changeset
   497
              'nohome': nohome, 'logfile': installerrs})
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   498
    vlog("# Running", cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   499
    if os.system(cmd) == 0:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   500
        if not options.verbose:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   501
            os.remove(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   502
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   503
        f = open(installerrs)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   504
        for line in f:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   505
            print line,
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   506
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   507
        sys.exit(1)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   508
    os.chdir(TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   509
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   510
    usecorrectpython()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   511
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   512
    if options.py3k_warnings and not options.anycoverage:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   513
        vlog("# Updating hg command to enable Py3k Warnings switch")
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   514
        f = open(os.path.join(BINDIR, 'hg'), 'r')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   515
        lines = [line.rstrip() for line in f]
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   516
        lines[0] += ' -3'
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   517
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   518
        f = open(os.path.join(BINDIR, 'hg'), 'w')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   519
        for line in lines:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   520
            f.write(line + '\n')
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   521
        f.close()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   522
943
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   523
    hgbat = os.path.join(BINDIR, 'hg.bat')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   524
    if os.path.isfile(hgbat):
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   525
        # 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
   526
        # 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
   527
        f = open(hgbat, 'rb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   528
        data = f.read()
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
        if '"%~dp0..\python" "%~dp0hg" %*' in data:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   531
            data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   532
                                '"%~dp0python" "%~dp0hg" %*')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   533
            f = open(hgbat, 'wb')
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   534
            f.write(data)
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   535
            f.close()
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   536
        else:
1f7fd6db1e17 run-tests: fix hg.bat python reference
Patrick Mezard <pmezard@gmail.com>
parents: 942
diff changeset
   537
            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
   538
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   539
    if options.anycoverage:
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   540
        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
   541
        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
   542
        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
   543
        shutil.copyfile(custom, target)
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   544
        rc = os.path.join(TESTDIR, '.coveragerc')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   545
        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
   546
        os.environ['COVERAGE_PROCESS_START'] = rc
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   547
        fn = os.path.join(INST, '..', '.coverage')
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   548
        os.environ['COVERAGE_FILE'] = fn
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   549
1159
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   550
def outputtimes(options):
b2bd669641d3 run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 1158
diff changeset
   551
    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
   552
    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
   553
    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
   554
    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
   555
    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
   556
        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
   557
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   558
def outputcoverage(options):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   559
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   560
    vlog('# Producing coverage report')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   561
    os.chdir(PYTHONDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   563
    def covrun(*args):
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   564
        cmd = 'coverage %s' % ' '.join(args)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   565
        vlog('# Running: %s' % cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   566
        os.system(cmd)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   567
718
88d7be7899ac tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 693
diff changeset
   568
    covrun('-c')
1038
62b7a0759ee3 run-tests: use a list comprehension instead of map
Matt Mackall <mpm@selenic.com>
parents: 1037
diff changeset
   569
    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
   570
    covrun('-i', '-r', '"--omit=%s"' % omit) # report
1039
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   571
    if options.htmlcov:
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   572
        htmldir = os.path.join(TESTDIR, 'htmlcov')
7c2190b236cf tests: add htmlcov option
Markus Zapke-Gr?ndemann <info@keimlink.de>
parents: 1038
diff changeset
   573
        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
   574
    if options.annotate:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   575
        adir = os.path.join(TESTDIR, 'annotated')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   576
        if not os.path.isdir(adir):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   577
            os.mkdir(adir)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   578
        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
   579
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   580
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
   581
    py3kswitch = options.py3k_warnings and ' -3' or ''
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   582
    cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
16f4cb2900fe tests: move script execution in runner helpers
Matt Mackall <mpm@selenic.com>
parents: 741
diff changeset
   583
    vlog("# Running", cmd)
1289
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   584
    if os.name == 'nt':
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   585
        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
   586
    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
   587
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   588
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
   589
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
   590
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
   591
escapemap.update({'\\': '\\\\', '\r': r'\r'})
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   592
def escapef(m):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   593
    return escapemap[m.group(0)]
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   594
def stringescape(s):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   595
    return escapesub(escapef, s)
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   596
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   597
def rematch(el, l):
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   598
    try:
1149
a3d0e19724c3 run-tests: alternative way of handling \r on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1143
diff changeset
   599
        # 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
   600
        if os.name == 'nt':
0b972f189962 run-tests: backout 4f32747879d1 line endings change
Matt Mackall <mpm@selenic.com>
parents: 1287
diff changeset
   601
            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
   602
        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
   603
    except re.error:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   604
        # el is an invalid regex
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   605
        return False
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   606
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   607
def globmatch(el, l):
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   608
    # The only supported special characters are * and ? plus / which also
1369
1161be3ff133 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 1368
diff changeset
   609
    # matches \ on windows. Escaping of these characters is supported.
1215
62ff53b05730 tests: quickly check if the glob line already matches the output
Simon Heimberg <simohe@besonet.ch>
parents: 1212
diff changeset
   610
    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
   611
        if os.altsep:
1216
192cebcd59a0 tests: inform on Windows about unnecessary glob lines
Simon Heimberg <simohe@besonet.ch>
parents: 1215
diff changeset
   612
            # 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
   613
            return '-glob'
1215
62ff53b05730 tests: quickly check if the glob line already matches the output
Simon Heimberg <simohe@besonet.ch>
parents: 1212
diff changeset
   614
        return True
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   615
    i, n = 0, len(el)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   616
    res = ''
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   617
    while i < n:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   618
        c = el[i]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   619
        i += 1
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   620
        if c == '\\' and el[i] in '*?\\/':
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   621
            res += el[i - 1:i + 1]
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   622
            i += 1
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   623
        elif c == '*':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   624
            res += '.*'
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   625
        elif c == '?':
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   626
            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
   627
        elif c == '/' and os.altsep:
1015
0a583943b4b4 tests: make (glob) on windows accept \ instead of /
Mads Kiilerich <mads@kiilerich.com>
parents: 1009
diff changeset
   628
            res += '[/\\\\]'
1001
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   629
        else:
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   630
            res += re.escape(c)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   631
    return rematch(res, l)
21b3c555b6f4 run-tests: pull out unified matching funcs
Matt Mackall <mpm@selenic.com>
parents: 1000
diff changeset
   632
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   633
def linematch(el, l):
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   634
    if el == l: # perfect match (fast)
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   635
        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
   636
    if el:
feb29f7d0066 run-tests: make it possible to combine (esc) with (glob) and (re)
Mads Kiilerich <mads@kiilerich.com>
parents: 1149
diff changeset
   637
        if el.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
   638
            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
   639
        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
   640
            return True
1319
b5ce8c72ddf9 run-tests: test each line matching function on its own
Simon Heimberg <simohe@besonet.ch>
parents: 1318
diff changeset
   641
        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
   642
            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
   643
        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
   644
            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
   645
        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
   646
            return '+glob'
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   647
    return False
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   648
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   649
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
   650
    # 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
   651
    # 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
   652
    # line number and the last return code
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   653
    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
   654
    def addsalt(line, inpython):
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   655
        if inpython:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   656
            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
   657
        else:
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   658
            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
   659
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   660
    # 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
   661
    # 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
   662
    # 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
   663
    # 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
   664
    after = {}
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   665
    pos = prepos = -1
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   666
1369
1161be3ff133 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 1368
diff changeset
   667
    # Expected shell script output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   668
    expected = {}
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   669
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   670
    # 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
   671
    # can generate the surrounding doctest magic
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   672
    inpython = False
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   673
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   674
    # 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
   675
    skipping = None
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   676
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   677
    def hghave(reqs):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   678
        # 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
   679
        tdir = TESTDIR.replace('\\', '/')
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   680
        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
   681
                      (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
   682
        stdout, stderr = proc.communicate()
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   683
        ret = proc.wait()
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   684
        if wifexited(ret):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   685
            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
   686
        if ret == 2:
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   687
            print stdout
e553e222bd7e tests: make hghave and run-tests exit on unknown feature requirements
Mads Kiilerich <mads@kiilerich.com>
parents: 1175
diff changeset
   688
            sys.exit(1)
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   689
        return ret == 0
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   690
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   691
    f = open(test)
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   692
    t = f.readlines()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   693
    f.close()
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   694
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   695
    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
   696
    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
   697
        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
   698
    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
   699
        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
   700
    n = 0
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   701
    for n, l in enumerate(t):
856
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   702
        if not l.endswith('\n'):
e1a5259b3d03 tests: handle .t files without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 852
diff changeset
   703
            l += '\n'
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   704
        if l.startswith('#if'):
1368
27b5b55ff3d3 tests: warn on invalid #if directive
Mads Kiilerich <madski@unity3d.com>
parents: 1366
diff changeset
   705
            lsplit = l.split()
27b5b55ff3d3 tests: warn on invalid #if directive
Mads Kiilerich <madski@unity3d.com>
parents: 1366
diff changeset
   706
            if len(lsplit) < 2 or lsplit[0] != '#if':
27b5b55ff3d3 tests: warn on invalid #if directive
Mads Kiilerich <madski@unity3d.com>
parents: 1366
diff changeset
   707
                after.setdefault(pos, []).append('  !!! invalid #if\n')
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   708
            if skipping is not None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   709
                after.setdefault(pos, []).append('  !!! nested #if\n')
1368
27b5b55ff3d3 tests: warn on invalid #if directive
Mads Kiilerich <madski@unity3d.com>
parents: 1366
diff changeset
   710
            skipping = not hghave(lsplit[1:])
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   711
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   712
        elif l.startswith('#else'):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   713
            if skipping is None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   714
                after.setdefault(pos, []).append('  !!! missing #if\n')
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   715
            skipping = not skipping
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   716
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   717
        elif l.startswith('#endif'):
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   718
            if skipping is None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   719
                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
   720
            skipping = None
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   721
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   722
        elif skipping:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   723
            after.setdefault(pos, []).append(l)
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   724
        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
   725
            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
   726
            prepos = pos
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   727
            pos = n
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   728
            if not inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   729
                # 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
   730
                inpython = True
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   731
                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
   732
                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
   733
            addsalt(n, True)
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   734
            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
   735
        elif l.startswith('  ... '): # python inlines
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   736
            after.setdefault(prepos, []).append(l)
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   737
            script.append(l[2:])
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   738
        elif l.startswith('  $ '): # commands
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   739
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   740
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   741
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   742
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   743
            prepos = pos
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   744
            pos = n
1005
d86b26020b48 run-tests: replace inline python handling with more native scheme
Matt Mackall <mpm@selenic.com>
parents: 1003
diff changeset
   745
            addsalt(n, False)
1093
660262879b48 tests: make .t tests stop immediately if a cd fails
Mads Kiilerich <mads@kiilerich.com>
parents: 1090
diff changeset
   746
            cmd = l[4:].split()
660262879b48 tests: make .t tests stop immediately if a cd fails
Mads Kiilerich <mads@kiilerich.com>
parents: 1090
diff changeset
   747
            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
   748
                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
   749
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   750
        elif l.startswith('  > '): # continuations
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   751
            after.setdefault(prepos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   752
            script.append(l[4:])
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   753
        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
   754
            # 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
   755
            expected.setdefault(pos, []).append(l[2:])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   756
        else:
999
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   757
            if inpython:
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   758
                script.append("EOF\n")
f89e9c528b38 tests: rewrite inline Python support
Matt Mackall <mpm@selenic.com>
parents: 996
diff changeset
   759
                inpython = False
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   760
            # non-command/result - queue up for merged output
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   761
            after.setdefault(pos, []).append(l)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   762
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   763
    if inpython:
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   764
        script.append("EOF\n")
1086
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   765
    if skipping is not None:
a2e8ccb65224 tests: introduce c-style conditional sections in .t tests
Mads Kiilerich <mads@kiilerich.com>
parents: 1085
diff changeset
   766
        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
   767
    addsalt(n + 1, False)
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   768
1003
59bd7f017103 run-tests: minor cleanups
Matt Mackall <mpm@selenic.com>
parents: 1002
diff changeset
   769
    # 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
   770
    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
   771
    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
   772
    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
   773
        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
   774
    f.close()
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   775
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
   776
    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
   777
    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
   778
    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
   779
    # 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
   780
    # 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
   781
    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
   782
        return exitcode, output
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   783
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   784
    # 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
   785
1348
2cb27f4b641c run-tests: fixed warn detection on failures with too many output
Simon Heimberg <simohe@besonet.ch>
parents: 1347
diff changeset
   786
    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
   787
    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
   788
        warnonly = 3 # set to "for sure not"
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   789
    pos = -1
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   790
    postout = []
1135
7c026ccf4e1a run-tests: drop unused enumerate
Mads Kiilerich <mads@kiilerich.com>
parents: 1131
diff changeset
   791
    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
   792
        lout, lcmd = l, None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   793
        if salt in l:
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   794
            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
   795
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   796
        if lout:
1138
bb419c4bfdd9 run-tests: use more explicit criteria for detecting no-eol
Mads Kiilerich <mads@kiilerich.com>
parents: 1135
diff changeset
   797
            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
   798
                lout += ' (no-eol)\n'
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   799
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   800
            # 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
   801
            el = None
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   802
            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
   803
                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
   804
1320
b82811d8ce22 run-tests: suggest to append glob when only path sep does not match
Simon Heimberg <simohe@besonet.ch>
parents: 1319
diff changeset
   805
            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
   806
            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
   807
                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
   808
                    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
   809
                    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
   810
                elif r == '-glob':
1340
fd5aa85ac2b9 run-tests: unnecessary globs also count as warnings
Simon Heimberg <simohe@besonet.ch>
parents: 1339
diff changeset
   811
                    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
   812
                    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
   813
                else:
79f68c0ed71e run-tests: print more information on unnecessary glob matching
Simon Heimberg <simohe@besonet.ch>
parents: 1320
diff changeset
   814
                    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
   815
                    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
   816
            if r:
1002
9a8202faebb3 run-tests: pull out line matching function
Matt Mackall <mpm@selenic.com>
parents: 1001
diff changeset
   817
                postout.append("  " + el)
857
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   818
            else:
858
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   819
                if needescape(lout):
ff1badf6ae7a tests: use (esc) markup for string-escape
Mads Kiilerich <mads@kiilerich.com>
parents: 857
diff changeset
   820
                    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
   821
                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
   822
                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
   823
                    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
   824
                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
   825
                    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
   826
7060aa668b7f tests: (no-eol) markup for command output without trailing LF
Mads Kiilerich <mads@kiilerich.com>
parents: 856
diff changeset
   827
        if lcmd:
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   828
            # 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
   829
            ret = int(lcmd.split()[1])
793
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   830
            if ret != 0:
9cc90e2c826f tests: add exit codes to unified tests
Matt Mackall <mpm@selenic.com>
parents: 777
diff changeset
   831
                postout.append("  [%s]\n" % ret)
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   832
            if pos in after:
1000
cc9cdab213e1 tests: add some comments to the unified test code
Matt Mackall <mpm@selenic.com>
parents: 999
diff changeset
   833
                # merge in non-active test bits
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   834
                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
   835
            pos = int(lcmd.split()[0])
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   836
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   837
    if pos in after:
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   838
        postout += after.pop(pos)
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   839
1348
2cb27f4b641c run-tests: fixed warn detection on failures with too many output
Simon Heimberg <simohe@besonet.ch>
parents: 1347
diff changeset
   840
    if warnonly == 2:
2cb27f4b641c run-tests: fixed warn detection on failures with too many output
Simon Heimberg <simohe@besonet.ch>
parents: 1347
diff changeset
   841
        exitcode = False # set exitcode to warned
776
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   842
    return exitcode, postout
1869efbf104d tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 775
diff changeset
   843
878
e1a93489159d run-tests: only call WIFEXITED on systems it exists
Simon Heimberg <simohe@besonet.ch>
parents: 877
diff changeset
   844
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
   845
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
   846
    """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
   847
    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
   848
    # 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
   849
    if options.debug:
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   850
        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
   851
        ret = proc.wait()
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   852
        return (ret, None)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
   853
1241
bc56ed64a2c8 run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 1240
diff changeset
   854
    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
   855
    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
   856
        terminate(proc)
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   857
        ret = proc.wait()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   858
        if ret == 0:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   859
            ret = signal.SIGTERM << 8
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   860
        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
   861
        return ret
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   862
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   863
    output = ''
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   864
    proc.tochild.close()
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   865
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   866
    try:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   867
        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
   868
    except KeyboardInterrupt:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   869
        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
   870
        cleanup()
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   871
        raise
682
1c7056415039 run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 681
diff changeset
   872
1281
3dc7d29a42e9 run-tests: lock popen wait/poll
Brendan Cully <brendan@kublai.com>
parents: 1280
diff changeset
   873
    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
   874
    if wifexited(ret):
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   875
        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
   876
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   877
    if proc.timeout:
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   878
        ret = 'timeout'
913
ee01b53f9ac9 run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 912
diff changeset
   879
945
83e828101e3c run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 944
diff changeset
   880
    if ret:
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
   881
        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
   882
1251
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   883
    if abort:
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   884
        raise KeyboardInterrupt()
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
   885
826
ac9b63e01e2a tests: replace test tmp directory with $TESTTMP in test output
Mads Kiilerich <mads@kiilerich.com>
parents: 824
diff changeset
   886
    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
   887
        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
   888
    return ret, output.splitlines(True)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   889
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   890
def runone(options, test, count):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   891
    '''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
   892
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   893
    def skip(msg):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   894
        if options.verbose:
1239
02112fca2ff3 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 1238
diff changeset
   895
            log("\nSkipping %s: %s" % (testpath, msg))
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   896
        return 's', test, msg
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   897
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   898
    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
   899
        warned = ret is False
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   900
        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
   901
            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
   902
        if (not ret and options.interactive
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   903
            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
   904
            iolock.acquire()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   905
            print "Accept this change? [n] ",
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   906
            answer = sys.stdin.readline().strip()
915
5660a21567b7 run-tests: fix some missing i/o locks
Matt Mackall <mpm@selenic.com>
parents: 914
diff changeset
   907
            iolock.release()
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   908
            if answer.lower() in "y yes".split():
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   909
                if test.endswith(".t"):
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   910
                    rename(testpath + ".err", testpath)
902
fb867941518c run-tests: move interactive handling into runone
Matt Mackall <mpm@selenic.com>
parents: 899
diff changeset
   911
                else:
910
b8ae2e290420 run-tests: fix --interactive (after 994ad067ac6e)
Patrick Mezard <pmezard@gmail.com>
parents: 909
diff changeset
   912
                    rename(testpath + ".err", testpath + ".out")
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
   913
                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
   914
        return warned and '~' or '!', test, msg
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   915
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   916
    def success():
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
   917
        return '.', test, ''
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   918
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
   919
    def ignore(msg):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   920
        return 'i', test, msg
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   921
1232
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   922
    def describe(ret):
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   923
        if ret < 0:
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   924
            return 'killed by signal %d' % -ret
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   925
        return 'returned error code %d' % ret
8730a2885d7c run-tests: regroup nested functions
Matt Mackall <mpm@selenic.com>
parents: 1231
diff changeset
   926
1233
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   927
    testpath = os.path.join(TESTDIR, test)
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   928
    err = os.path.join(TESTDIR, test + ".err")
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   929
    lctest = test.lower()
e15c19e34344 run-tests: regroup some variable initialization
Matt Mackall <mpm@selenic.com>
parents: 1232
diff changeset
   930
1234
750a0ed6f380 run-tests: fix a path existence check
Matt Mackall <mpm@selenic.com>
parents: 1233
diff changeset
   931
    if not os.path.exists(testpath):
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
   932
            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
   933
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   934
    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
   935
        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
   936
            return skip("blacklisted")
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   937
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   938
        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
   939
            return ignore("not retesting")
907
edf2753d3170 run-tests: move blacklist and retest filtering to runone
Matt Mackall <mpm@selenic.com>
parents: 906
diff changeset
   940
962
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   941
        if options.keywords:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   942
            fp = open(test)
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   943
            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
   944
            fp.close()
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   945
            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
   946
                if k in t:
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   947
                    break
b5a4f9f5ec49 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 960
diff changeset
   948
                else:
1272
4a224ed7e923 run-tests: ignoring tests works again
simon@laptop-tosh
parents: 1270
diff changeset
   949
                    return ignore("doesn't match keyword")
905
66b8706b3112 run-tests: move keyword checking into runone
Matt Mackall <mpm@selenic.com>
parents: 904
diff changeset
   950
1366
987a80dec7db run-tests: allow test paths in other directories
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1365
diff changeset
   951
    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
   952
        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
   953
    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
   954
        if lctest.endswith(ext):
1227
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   955
            runner = func
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
   956
            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
   957
            break
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   958
    else:
1152
9a4ed3acf89e run-tests: remove dead code for supporting old test scripts
Mads Kiilerich <mads@kiilerich.com>
parents: 1151
diff changeset
   959
        return skip("unknown test type")
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   960
1235
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   961
    vlog("# Test", test)
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   962
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   963
    if os.path.exists(err):
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   964
        os.remove(err)       # Remove any previous output files
8fd26ac1deca run-tests: regroup some initialization checks
Matt Mackall <mpm@selenic.com>
parents: 1234
diff changeset
   965
693
8428f3bda904 run-tests.py: skipped tests shouldn't change working directory
Mads Kiilerich <mads@kiilerich.com>
parents: 692
diff changeset
   966
    # Make a tmp subdirectory to work in
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   967
    threadtmp = os.path.join(HGTMP, "child%d" % count)
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   968
    testtmp = os.path.join(threadtmp, os.path.basename(test))
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
   969
    os.mkdir(threadtmp)
1231
c6a4dd8d18a9 run-tests: regroup temp dir creation
Matt Mackall <mpm@selenic.com>
parents: 1230
diff changeset
   970
    os.mkdir(testtmp)
895
1a9cd0b534a0 tests: set HOME to the test temp dir (issue2707)
Idan Kamara <idankk86@gmail.com>
parents: 882
diff changeset
   971
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   972
    port = options.port + count * 3
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   973
    replacements = [
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   974
        (r':%s\b' % port, ':$HGPORT'),
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   975
        (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
   976
        (r':%s\b' % (port + 2), ':$HGPORT2'),
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   977
        ]
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   978
    if os.name == 'nt':
1019
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   979
        replacements.append(
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   980
            (''.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
   981
                     c in '/\\' and r'[/\\]' or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   982
                     c.isdigit() and c or
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   983
                     '\\' + c
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   984
                     for c in testtmp), '$TESTTMP'))
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   985
    else:
e7fbd63e5a98 run-tests: make $TESTTMP matching case-insensitive on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1018
diff changeset
   986
        replacements.append((re.escape(testtmp), '$TESTTMP'))
1017
9cd561108da4 tests: ignore \r on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 1016
diff changeset
   987
1253
79e201b6826a run-tests: use count to calculate port to use
Matt Mackall <mpm@selenic.com>
parents: 1252
diff changeset
   988
    env = createenv(options, testtmp, threadtmp, port)
1246
e6ba976e152c run-tests: move HGRCPATH to env
Matt Mackall <mpm@selenic.com>
parents: 1245
diff changeset
   989
    createhgrc(env['HGRCPATH'], options)
e6ba976e152c run-tests: move HGRCPATH to env
Matt Mackall <mpm@selenic.com>
parents: 1245
diff changeset
   990
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   991
    starttime = time.time()
1266
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   992
    try:
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   993
        ret, out = runner(testpath, testtmp, options, replacements, env)
f412189fe8f8 run-tests: report interrupted tests
Simon Heimberg <simohe@besonet.ch>
parents: 1265
diff changeset
   994
    except KeyboardInterrupt:
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   995
        endtime = time.time()
1270
79e0df6ffaad run-tests: simplify interrupted message
Matt Mackall <mpm@selenic.com>
parents: 1269
diff changeset
   996
        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
   997
        raise
1268
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   998
    endtime = time.time()
6133577ca4f6 run-tests: always gather runtimes
Matt Mackall <mpm@selenic.com>
parents: 1267
diff changeset
   999
    times.append((test, endtime - starttime))
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1000
    vlog("# Ret was:", ret)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1001
1242
2d7fa9712652 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 1241
diff changeset
  1002
    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
  1003
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1004
    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
  1005
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1006
    # 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
  1007
    # check test output against it.
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1008
    if options.debug:
866
d51c3fd4e34a code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 862
diff changeset
  1009
        refout = None                   # to match "out is None"
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1010
    elif os.path.exists(ref):
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1011
        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
  1012
        refout = f.read().splitlines(True)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1013
        f.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1014
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1015
        refout = []
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1016
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1017
    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
  1018
        # 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
  1019
        f = open(err, "wb")
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1020
        for line in out:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1021
            f.write(line)
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1022
        f.close()
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1023
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1024
    if skipped:
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1025
        if out is None:                 # debug mode: nothing to parse
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1026
            missing = ['unknown']
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1027
            failed = None
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1028
        else:
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1029
            missing, failed = parsehghaveoutput(out)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1030
        if not missing:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1031
            missing = ['irrelevant']
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1032
        if failed:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1033
            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
  1034
            skipped = False
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1035
        else:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1036
            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
  1037
    elif ret == 'timeout':
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1038
        result = fail("timed out", ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1039
    elif out != refout:
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1040
        info = {}
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1041
        if not options.nodiff:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1042
            iolock.acquire()
741
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1043
            if options.view:
e5bfe51eeea9 run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 740
diff changeset
  1044
                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
  1045
            else:
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1046
                info = 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
  1047
            iolock.release()
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1048
        msg = ""
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1049
        if info.get('servefail'): msg += "serve failed and "
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1050
        if ret:
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1051
            msg += "output changed and " + describe(ret)
916
dd5c50a018b0 run-tests: display diff before prompting with --interactive
Patrick Mezard <pmezard@gmail.com>
parents: 915
diff changeset
  1052
        else:
1370
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1053
            msg += "output changed"
d6cab997a43e run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 1369
diff changeset
  1054
        result = fail(msg, ret)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1055
    elif ret:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1056
        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
  1057
    else:
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1058
        result = success()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1059
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1060
    if not options.verbose:
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1061
        iolock.acquire()
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1062
        sys.stdout.write(result[0])
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1063
        sys.stdout.flush()
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1064
        iolock.release()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1065
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1066
    if not options.keep_tmpdir:
1252
e9ad07011f87 run-tests: introduce threadtmp directory
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
  1067
        shutil.rmtree(threadtmp, True)
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1068
    return result
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1069
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1070
_hgpath = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1071
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1072
def _gethgpath():
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1073
    """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
  1074
    the current Python interpreter."""
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1075
    global _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1076
    if _hgpath is not None:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1077
        return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1078
1293
6e9bfd51bc6f run-tests: find mercurial path with syntax valid on both py2 and py3
Augie Fackler <raf@durin42.com>
parents: 1292
diff changeset
  1079
    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
  1080
    pipe = os.popen(cmd % PYTHON)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1081
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1082
        _hgpath = pipe.read().strip()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1083
    finally:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1084
        pipe.close()
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1085
    return _hgpath
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1086
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1087
def _checkhglib(verb):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1088
    """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
  1089
    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
  1090
    expecthg = os.path.join(PYTHONDIR, 'mercurial')
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1091
    actualhg = _gethgpath()
934
cf241f12e977 run-tests: compare absolute paths in _checkhglib
Idan Kamara <idankk86@gmail.com>
parents: 932
diff changeset
  1092
    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
  1093
        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
  1094
                         '         (expected %s)\n'
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1095
                         % (verb, actualhg, expecthg))
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1096
1336
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1097
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
  1098
times = []
914
3c57e9963070 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 913
diff changeset
  1099
iolock = threading.Lock()
1251
5dfbf34da361 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 1250
diff changeset
  1100
abort = False
912
17e4691cc491 run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 910
diff changeset
  1101
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1102
def scheduletests(options, tests):
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1103
    jobs = options.jobs
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1104
    done = queue.Queue()
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1105
    running = 0
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1106
    count = 0
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1107
    global abort
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1108
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1109
    def job(test, count):
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1110
        try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1111
            done.put(runone(options, test, count))
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1112
        except KeyboardInterrupt:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1113
            pass
1317
f7923ea4b188 run-tests: report tests as failed when run-test raises an error
Simon Heimberg <simohe@besonet.ch>
parents: 1313
diff changeset
  1114
        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
  1115
            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
  1116
            raise
1236
b1062bc760a9 run-tests: change return code of runone
Matt Mackall <mpm@selenic.com>
parents: 1235
diff changeset
  1117
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1118
    try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1119
        while tests or running:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1120
            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
  1121
                try:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1122
                    code, test, msg = done.get(True, 1)
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1123
                    results[code].append((test, msg))
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1124
                    if options.first and code not in '.si':
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1125
                        break
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1126
                except queue.Empty:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1127
                    continue
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1128
                running -= 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1129
            if tests and not running == jobs:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1130
                test = tests.pop(0)
1261
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
  1131
                if options.loop:
13890d7a70b1 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 1260
diff changeset
  1132
                    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
  1133
                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
  1134
                t.start()
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1135
                running += 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1136
                count += 1
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1137
    except KeyboardInterrupt:
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1138
        abort = True
909
5ec26580cbb2 run-tests: move test loop into a helper function
Matt Mackall <mpm@selenic.com>
parents: 908
diff changeset
  1139
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1140
def runtests(options, tests):
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1141
    try:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1142
        if INST:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1143
            installhg(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1144
            _checkhglib("Testing")
1168
96a0960a7909 run-tests: use correct python when run with --local
Bryan O'Sullivan <bryano@fb.com>
parents: 1166
diff changeset
  1145
        else:
96a0960a7909 run-tests: use correct python when run with --local
Bryan O'Sullivan <bryano@fb.com>
parents: 1166
diff changeset
  1146
            usecorrectpython()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1147
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1148
        if options.restart:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1149
            orig = list(tests)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1150
            while tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1151
                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
  1152
                    break
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1153
                tests.pop(0)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1154
            if not tests:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1155
                print "running all tests"
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1156
                tests = orig
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1157
1254
1642fcc7e2a1 run-tests: introduce thread scheduler
Matt Mackall <mpm@selenic.com>
parents: 1253
diff changeset
  1158
        scheduletests(options, tests)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1159
1237
ac098555f410 run-tests: unify marks and result codes
Matt Mackall <mpm@selenic.com>
parents: 1236
diff changeset
  1160
        failed = len(results['!'])
1336
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1161
        warned = len(results['~'])
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1162
        tested = len(results['.']) + failed + warned
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1163
        skipped = len(results['s'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1164
        ignored = len(results['i'])
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1165
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1166
        print
1263
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1167
        if not options.noskips:
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1168
            for s in results['s']:
f31eefe0ab4c run-tests: make --noskips work
Matt Mackall <mpm@selenic.com>
parents: 1261
diff changeset
  1169
                print "Skipped %s: %s" % s
1336
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1170
        for s in results['~']:
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1171
            print "Warned %s: %s" % s
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1172
        for s in results['!']:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1173
            print "Failed %s: %s" % s
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1174
        _checkhglib("Tested")
1336
c213fb7b786f run-tests: introduce 'warned' as test result
Simon Heimberg <simohe@besonet.ch>
parents: 1335
diff changeset
  1175
        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
  1176
            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
  1177
        if results['!']:
164ed9bf157c tests: python hash seed is only relevant after failures - otherwise keep quiet
Mads Kiilerich <madski@unity3d.com>
parents: 1305
diff changeset
  1178
            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
  1179
        if options.time:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1180
            outputtimes(options)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1181
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1182
        if options.anycoverage:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1183
            outputcoverage(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1184
    except KeyboardInterrupt:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1185
        failed = True
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1186
        print "\ninterrupted!"
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1187
908
78f81dc655ca run-tests: use a results dict
Matt Mackall <mpm@selenic.com>
parents: 907
diff changeset
  1188
    if failed:
1335
d15090c7d555 run-tests: handle sys.exit in main function
Simon Heimberg <simohe@besonet.ch>
parents: 1334
diff changeset
  1189
        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
  1190
    if warned:
6810b3c166cc run-tests: separate exit code when no failed tests but warned ones
Simon Heimberg <simohe@besonet.ch>
parents: 1336
diff changeset
  1191
        return 80
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1192
1227
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1193
testtypes = [('.py', pytest, '.out'),
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1194
             ('.t', tsttest, '')]
afafc1812f7b run-tests: make a table of test types
Matt Mackall <mpm@selenic.com>
parents: 1226
diff changeset
  1195
1365
51476d2dcab1 run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1364
diff changeset
  1196
def main(args, parser=None):
51476d2dcab1 run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1364
diff changeset
  1197
    parser = parser or getparser()
51476d2dcab1 run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1364
diff changeset
  1198
    (options, args) = parseargs(args, parser)
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1199
    os.umask(022)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1200
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1201
    checktools()
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1202
1358
805a5c2fe9c8 tests: small refactoring of run-tests' handling of tests list
Mads Kiilerich <madski@unity3d.com>
parents: 1355
diff changeset
  1203
    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
  1204
        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
  1205
            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
  1206
                          None, 0)
1d3aa8779efb tests: add run-tests --changed option for running tests changed in revisions
Mads Kiilerich <madski@unity3d.com>
parents: 1358
diff changeset
  1207
            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
  1208
            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
  1209
        else:
1d3aa8779efb tests: add run-tests --changed option for running tests changed in revisions
Mads Kiilerich <madski@unity3d.com>
parents: 1358
diff changeset
  1210
            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
  1211
1358
805a5c2fe9c8 tests: small refactoring of run-tests' handling of tests list
Mads Kiilerich <madski@unity3d.com>
parents: 1355
diff changeset
  1212
    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
  1213
             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
  1214
                 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
  1215
1221
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
  1216
    if options.random:
3a049b21a05b run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 1219
diff changeset
  1217
        random.shuffle(tests)
1255
ac0cc929e982 run-tests: schedule largest tests first
Matt Mackall <mpm@selenic.com>
parents: 1254
diff changeset
  1218
    else:
1259
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1219
        # keywords for slow tests
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1220
        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
  1221
        def sortkey(f):
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1222
            # 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
  1223
            try:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1224
                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
  1225
            except OSError, e:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1226
                if e.errno != errno.ENOENT:
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1227
                    raise
f1a4e67c41fe run-tests: sort missing files first instead of raising an error
simon@laptop-tosh
parents: 1273
diff changeset
  1228
                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
  1229
            for kw in slow:
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1230
                if kw in f:
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1231
                    val *= 10
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1232
            return val
71fcece633e4 run-tests: sort certain slow tests earlier by keyword
Matt Mackall <mpm@selenic.com>
parents: 1258
diff changeset
  1233
        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
  1234
1212
2ea362720f72 test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 1210
diff changeset
  1235
    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
  1236
        # 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
  1237
        # 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
  1238
        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
  1239
1343
958582800276 run-tests.py: work when --with-hg is set to system hg
Siddharth Agarwal <sid0@fb.com>
parents: 1341
diff changeset
  1240
    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
  1241
    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1242
    if options.tmpdir:
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1243
        options.keep_tmpdir = True
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1244
        tmpdir = options.tmpdir
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1245
        if os.path.exists(tmpdir):
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1246
            # 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
  1247
            # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1248
            # tmpdir already exists.
1364
772a53435e14 run-tests: use return values instead of sys.exit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1363
diff changeset
  1249
            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
  1250
            return 1
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1251
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1252
            # Automatically removing tmpdir sounds convenient, but could
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1253
            # really annoy anyone in the habit of using "--tmpdir=/tmp"
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1254
            # or "--tmpdir=$HOME".
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1255
            #vlog("# Removing temp dir", tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1256
            #shutil.rmtree(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1257
        os.makedirs(tmpdir)
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1258
    else:
1088
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1259
        d = None
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1260
        if os.name == 'nt':
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1261
            # 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
  1262
            # 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
  1263
            d = os.getenv('TMP')
e2d5315a6e38 tests/run-tests: use $TMP on Windows (issue3490)
Adrian Buehlmann <adrian@cadifra.com>
parents: 1086
diff changeset
  1264
        tmpdir = tempfile.mkdtemp('', 'hgtests.', d)
670
80d0ed025a02 run-tests.py: update
Christian Ebert <blacktrash@gmx.net>
parents: 562
diff changeset
  1265
    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
  1266
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1267
    if options.with_hg:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1268
        INST = None
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1269
        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
  1270
        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
  1271
        os.makedirs(TMPBINDIR)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1272
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1273
        # 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
  1274
        # 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
  1275
        # "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
  1276
        # 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
  1277
        # ... 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
  1278
        PYTHONDIR = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1279
    else:
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1280
        INST = os.path.join(HGTMP, "install")
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1281
        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
  1282
        TMPBINDIR = BINDIR
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1283
        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
  1284
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1285
    os.environ["BINDIR"] = BINDIR
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1286
    os.environ["PYTHON"] = PYTHON
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1287
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1288
    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
  1289
    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
  1290
        path = [TMPBINDIR] + path
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1291
    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
  1292
1257
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1293
    # 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
  1294
    # 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
  1295
    # 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
  1296
    # modules like heredoctest.
c559280de767 run-tests: fix heredoctest for out-of-tree extensions
Patrick Mezard <patrick@mezard.eu>
parents: 1340
diff changeset
  1297
    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
  1298
    # 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
  1299
    # 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
  1300
    # 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
  1301
    # are in /opt/subversion.)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1302
    oldpypath = os.environ.get(IMPL_PATH)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1303
    if oldpypath:
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1304
        pypath.append(oldpypath)
d1cc63bb278f run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 1256
diff changeset
  1305
    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
  1306
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1307
    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
  1308
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1309
    vlog("# Using TESTDIR", TESTDIR)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1310
    vlog("# Using HGTMP", HGTMP)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1311
    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
  1312
    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
  1313
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1314
    try:
1364
772a53435e14 run-tests: use return values instead of sys.exit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1363
diff changeset
  1315
        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
  1316
    finally:
1059
1745fd2dd308 tests: shorten post-test sleeps
Matt Mackall <mpm@selenic.com>
parents: 1046
diff changeset
  1317
        time.sleep(.1)
562
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1318
        cleanup(options)
b1aa7b64890b Add run-tests.py from main and update README
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
  1319
877
c2ca6e172fd8 run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 866
diff changeset
  1320
if __name__ == '__main__':
1364
772a53435e14 run-tests: use return values instead of sys.exit
Gregory Szorc <gregory.szorc@gmail.com>
parents: 1363
diff changeset
  1321
    sys.exit(main(sys.argv[1:]))