tests/run-tests.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sun, 20 Apr 2014 16:44:45 -0700
changeset 21464 d19164a018a1
parent 21463 c908ff887589
child 21488 feb8ad2d57ee
permissions -rwxr-xr-x
run-tests: execute tests via unittest Now that unittest mode is functionally equivalent to the default mode, we switch the default execution mode to unittest and remove the choice of different execution modes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     1
#!/usr/bin/env python
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     2
#
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     3
# run-tests.py - Run a set of tests on Mercurial
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     4
#
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     5
# Copyright 2006 Matt Mackall <mpm@selenic.com>
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     6
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8161
diff changeset
     7
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10154
diff changeset
     8
# GNU General Public License version 2 or any later version.
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
     9
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    10
# Modifying this script is tricky because it has many modes:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    11
#   - serial (default) vs parallel (-jN, N > 1)
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    12
#   - no coverage (default) vs coverage (-c, -C, -s)
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    13
#   - temp install (default) vs specific hg script (--with-hg, --local)
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    14
#   - tests are a mix of shell scripts and Python scripts
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    15
#
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    16
# If you change this script, it is recommended that you ensure you
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    17
# haven't broken it by running it in various modes with a representative
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    18
# sample of test scripts.  For example:
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8724
diff changeset
    19
#
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    20
#  1) serial, no coverage, temp install:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    21
#      ./run-tests.py test-s*
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    22
#  2) serial, no coverage, local hg:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    23
#      ./run-tests.py --local test-s*
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    24
#  3) serial, coverage, temp install:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    25
#      ./run-tests.py -c test-s*
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    26
#  4) serial, coverage, local hg:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    27
#      ./run-tests.py -c --local test-s*      # unsupported
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    28
#  5) parallel, no coverage, temp install:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    29
#      ./run-tests.py -j2 test-s*
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    30
#  6) parallel, no coverage, local hg:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    31
#      ./run-tests.py -j2 --local test-s*
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    32
#  7) parallel, coverage, temp install:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    33
#      ./run-tests.py -j2 -c test-s*          # currently broken
9899
be574a37a8ae run-tests: give each child its own tmp dir (issue1911)
Greg Ward <greg@gerg.ca>
parents: 9707
diff changeset
    34
#  8) parallel, coverage, local install:
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    35
#      ./run-tests.py -j2 -c --local test-s*  # unsupported (and broken)
9899
be574a37a8ae run-tests: give each child its own tmp dir (issue1911)
Greg Ward <greg@gerg.ca>
parents: 9707
diff changeset
    36
#  9) parallel, custom tmp dir:
be574a37a8ae run-tests: give each child its own tmp dir (issue1911)
Greg Ward <greg@gerg.ca>
parents: 9707
diff changeset
    37
#      ./run-tests.py -j2 --tmpdir /tmp/myhgtests
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    38
#
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    39
# (You could use any subset of the tests: test-s* happens to match
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    40
# enough that it's worth doing parallel runs, few enough that it
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    41
# completes fairly quickly, includes both shell and Python scripts, and
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    42
# includes some scripts that run daemon processes.)
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
    43
10648
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
    44
from distutils import version
2571
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    45
import difflib
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    46
import errno
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    47
import optparse
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    48
import os
10905
13a1b2fb7ef2 pylint, pyflakes: remove unused or duplicate imports
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10903
diff changeset
    49
import shutil
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    50
import subprocess
2571
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    51
import signal
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    52
import sys
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
    53
import tempfile
2571
83cfd95eafb5 tests: add timeouts, make run-tests.py clean up dead daemon processes
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2570
diff changeset
    54
import time
18616
35b4affe6fdd test: display used python hash seed
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18565
diff changeset
    55
import random
11741
431e2bf37ae7 tests: basic support for unified tests
Matt Mackall <mpm@selenic.com>
parents: 11740
diff changeset
    56
import re
14000
636a6f5aa2cd run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 13999
diff changeset
    57
import threading
17464
eddfb9a550d0 run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 16906
diff changeset
    58
import killdaemons as killmod
18057
6b88ded2a993 run-tests: support running tests in parallel on windows
Bryan O'Sullivan <bryano@fb.com>
parents: 18050
diff changeset
    59
import Queue as queue
21426
791bdd65acd3 run-tests: initial support for running tests with unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21388
diff changeset
    60
import unittest
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
    61
14019
fbbd5f91d5e1 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 14018
diff changeset
    62
processlock = threading.Lock()
19413
a4de0d3dc35a run-tests: lock popen wait/poll
Brendan Cully <brendan@kublai.com>
parents: 19407
diff changeset
    63
19415
a0699972e75a run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 19414
diff changeset
    64
# subprocess._cleanup can race with any Popen.wait or Popen.poll on py24
a0699972e75a run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 19414
diff changeset
    65
# http://bugs.python.org/issue1731717 for details. We shouldn't be producing
a0699972e75a run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 19414
diff changeset
    66
# zombies but it's pretty harmless even if we do.
20219
f694cd81b600 run-tests: better check for python version
Simon Heimberg <simohe@besonet.ch>
parents: 20046
diff changeset
    67
if sys.version_info < (2, 5):
19415
a0699972e75a run-tests: replace popen locking with a noop _cleanup handler on py24
Brendan Cully <brendan@kublai.com>
parents: 19414
diff changeset
    68
    subprocess._cleanup = lambda: None
14019
fbbd5f91d5e1 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 14018
diff changeset
    69
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    70
closefds = os.name == 'posix'
19262
7864e8f274fe run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 19252
diff changeset
    71
def Popen4(cmd, wd, timeout, env=None):
14019
fbbd5f91d5e1 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 14018
diff changeset
    72
    processlock.acquire()
19262
7864e8f274fe run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 19252
diff changeset
    73
    p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env,
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    74
                         close_fds=closefds,
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    75
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE,
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    76
                         stderr=subprocess.STDOUT)
14019
fbbd5f91d5e1 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 14018
diff changeset
    77
    processlock.release()
fbbd5f91d5e1 run-tests: do chdir for tests under a lock for thread safety
Matt Mackall <mpm@selenic.com>
parents: 14018
diff changeset
    78
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    79
    p.fromchild = p.stdout
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    80
    p.tochild = p.stdin
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    81
    p.childerr = p.stderr
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    82
14337
439ed4721a6d run-tests: ignore timeout when Popen.terminate is unavailable
Patrick Mezard <pmezard@gmail.com>
parents: 14336
diff changeset
    83
    p.timeout = False
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    84
    if timeout:
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    85
        def t():
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    86
            start = time.time()
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    87
            while time.time() - start < timeout and p.returncode is None:
16346
48692b416fbc tests: shorten post-test sleeps
Matt Mackall <mpm@selenic.com>
parents: 15942
diff changeset
    88
                time.sleep(.1)
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    89
            p.timeout = True
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    90
            if p.returncode is None:
14821
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
    91
                terminate(p)
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    92
        threading.Thread(target=t).start()
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
    93
8280
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    94
    return p
0b02d98d44d0 util: always use subprocess
Martin Geisler <mg@lazybytes.net>
parents: 8258
diff changeset
    95
15448
873f94ecd706 run-tests: convert windows paths to unix
Mads Kiilerich <mads@kiilerich.com>
parents: 15447
diff changeset
    96
PYTHON = sys.executable.replace('\\', '/')
10758
2ed667a9dfcb tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10750
diff changeset
    97
IMPL_PATH = 'PYTHONPATH'
2ed667a9dfcb tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10750
diff changeset
    98
if 'java' in sys.platform:
2ed667a9dfcb tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10750
diff changeset
    99
    IMPL_PATH = 'JYTHONPATH'
4881
c51c9bc4579d Add hghave utility and run-tests.py support.
Patrick Mezard <pmezard@gmail.com>
parents: 4880
diff changeset
   100
21231
1ce16c7b7fb4 run-tests: initialize global variables to suppress pyflakes warning
Yuya Nishihara <yuya@tcha.org>
parents: 21024
diff changeset
   101
TESTDIR = HGTMP = INST = BINDIR = TMPBINDIR = PYTHONDIR = None
1ce16c7b7fb4 run-tests: initialize global variables to suppress pyflakes warning
Yuya Nishihara <yuya@tcha.org>
parents: 21024
diff changeset
   102
6366
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   103
defaults = {
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   104
    'jobs': ('HGTEST_JOBS', 1),
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   105
    'timeout': ('HGTEST_TIMEOUT', 180),
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   106
    'port': ('HGTEST_PORT', 20059),
15941
af289d6cd422 tests: let run-tests.py default to use 'sh' in $PATH instead of '/bin/sh'
Mads Kiilerich <mads@kiilerich.com>
parents: 15940
diff changeset
   107
    'shell': ('HGTEST_SHELL', 'sh'),
6366
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   108
}
07c3cd695b48 run-tests.py: Allow environment variables to set jobs/timeout/port.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6343
diff changeset
   109
14493
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   110
def parselistfiles(files, listtype, warn=True):
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   111
    entries = dict()
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   112
    for filename in files:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   113
        try:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   114
            path = os.path.expanduser(os.path.expandvars(filename))
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   115
            f = open(path, "r")
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   116
        except IOError, err:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   117
            if err.errno != errno.ENOENT:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   118
                raise
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   119
            if warn:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   120
                print "warning: no such %s file: %s" % (listtype, filename)
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   121
            continue
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   122
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   123
        for line in f.readlines():
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   124
            line = line.split('#', 1)[0].strip()
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   125
            if line:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   126
                entries[line] = filename
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   127
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   128
        f.close()
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   129
    return entries
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   130
21008
c1dd04be3d9a run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21007
diff changeset
   131
def getparser():
21383
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   132
    """Obtain the OptionParser used by the CLI."""
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   133
    parser = optparse.OptionParser("%prog [options] [tests]")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   134
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   135
    # keep these sorted
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   136
    parser.add_option("--blacklist", action="append",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   137
        help="skip tests listed in the specified blacklist file")
14493
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   138
    parser.add_option("--whitelist", action="append",
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   139
        help="always run tests listed in the specified whitelist file")
20821
3d1d16b19e7d tests: add run-tests --changed option for running tests changed in revisions
Mads Kiilerich <madski@unity3d.com>
parents: 20793
diff changeset
   140
    parser.add_option("--changed", type="string",
3d1d16b19e7d tests: add run-tests --changed option for running tests changed in revisions
Mads Kiilerich <madski@unity3d.com>
parents: 20793
diff changeset
   141
        help="run tests that are changed in parent rev or working directory")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   142
    parser.add_option("-C", "--annotate", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   143
        help="output files annotated with coverage")
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   144
    parser.add_option("-c", "--cover", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   145
        help="print a test coverage report")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   146
    parser.add_option("-d", "--debug", action="store_true",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   147
        help="debug mode: write output of test scripts to console"
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 21023
diff changeset
   148
             " rather than capturing and diffing it (disables timeout)")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   149
    parser.add_option("-f", "--first", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   150
        help="exit on the first test failure")
15859
44a371823f83 tests: add htmlcov option
Markus Zapke-Gründemann <info@keimlink.de>
parents: 15858
diff changeset
   151
    parser.add_option("-H", "--htmlcov", action="store_true",
44a371823f83 tests: add htmlcov option
Markus Zapke-Gründemann <info@keimlink.de>
parents: 15858
diff changeset
   152
        help="create an HTML report of the coverage of the files")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   153
    parser.add_option("-i", "--interactive", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   154
        help="prompt to accept changed output")
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   155
    parser.add_option("-j", "--jobs", type="int",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   156
        help="number of jobs to run in parallel"
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   157
             " (default: $%s or %d)" % defaults['jobs'])
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   158
    parser.add_option("--keep-tmpdir", action="store_true",
9706
f8b4df4b033d run-tests: make --tmpdir option more useful.
Greg Ward <greg-hg@gerg.ca>
parents: 9582
diff changeset
   159
        help="keep temporary directory after running tests")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   160
    parser.add_option("-k", "--keywords",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   161
        help="run tests matching keywords")
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   162
    parser.add_option("-l", "--local", action="store_true",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   163
        help="shortcut for --with-hg=<testdir>/../hg")
19283
8300adf9ca33 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 19282
diff changeset
   164
    parser.add_option("--loop", action="store_true",
8300adf9ca33 run-tests: add --loop support
Matt Mackall <mpm@selenic.com>
parents: 19282
diff changeset
   165
        help="loop tests repeatedly")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   166
    parser.add_option("-n", "--nodiff", action="store_true",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   167
        help="skip showing test changes")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   168
    parser.add_option("-p", "--port", type="int",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   169
        help="port on which servers should listen"
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   170
             " (default: $%s or %d)" % defaults['port'])
17966
ae20cde050c2 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 17965
diff changeset
   171
    parser.add_option("--compiler", type="string",
ae20cde050c2 run-tests: add a --compiler option
Bryan O'Sullivan <bryano@fb.com>
parents: 17965
diff changeset
   172
        help="compiler to build with")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   173
    parser.add_option("--pure", action="store_true",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   174
        help="use pure Python code instead of C extensions")
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   175
    parser.add_option("-R", "--restart", action="store_true",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   176
        help="restart at last error")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   177
    parser.add_option("-r", "--retest", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   178
        help="retest failed tests")
9580
25858f9e65e8 run-tests: add --noskips option
Matt Mackall <mpm@selenic.com>
parents: 9408
diff changeset
   179
    parser.add_option("-S", "--noskips", action="store_true",
25858f9e65e8 run-tests: add --noskips option
Matt Mackall <mpm@selenic.com>
parents: 9408
diff changeset
   180
        help="don't report skip tests verbosely")
14202
b68a41420397 run-tests: add --shell command line flag
Martin Geisler <mg@lazybytes.net>
parents: 14201
diff changeset
   181
    parser.add_option("--shell", type="string",
b68a41420397 run-tests: add --shell command line flag
Martin Geisler <mg@lazybytes.net>
parents: 14201
diff changeset
   182
        help="shell to use (default: $%s or %s)" % defaults['shell'])
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   183
    parser.add_option("-t", "--timeout", type="int",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   184
        help="kill errant tests after TIMEOUT seconds"
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   185
             " (default: $%s or %d)" % defaults['timeout'])
17921
4ac9cf3d810c run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 17920
diff changeset
   186
    parser.add_option("--time", action="store_true",
4ac9cf3d810c run-tests: add --time option to log times for each test
Siddharth Agarwal <sid0@fb.com>
parents: 17920
diff changeset
   187
        help="time how long each test takes")
11039
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   188
    parser.add_option("--tmpdir", type="string",
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   189
        help="run tests in the given temporary directory"
cf0a309f6c4d run-tests: sort options
Matt Mackall <mpm@selenic.com>
parents: 11038
diff changeset
   190
             " (implies --keep-tmpdir)")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   191
    parser.add_option("-v", "--verbose", action="store_true",
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   192
        help="output verbose messages")
11040
8f951ed6c63c run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 11039
diff changeset
   193
    parser.add_option("--view", type="string",
8f951ed6c63c run-tests: add --view switch to use external diff viewer
Matt Mackall <mpm@selenic.com>
parents: 11039
diff changeset
   194
        help="external diff viewer")
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   195
    parser.add_option("--with-hg", type="string",
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   196
        metavar="HG",
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   197
        help="test using specified hg script rather than a "
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   198
             "temporary installation")
9028
bea567ae3ff6 tests: add -3 switch to run-tests.py
Alejandro Santos <alejolp@alejolp.com>
parents: 8943
diff changeset
   199
    parser.add_option("-3", "--py3k-warnings", action="store_true",
bea567ae3ff6 tests: add -3 switch to run-tests.py
Alejandro Santos <alejolp@alejolp.com>
parents: 8943
diff changeset
   200
        help="enable Py3k warnings on Python 2.6+")
14134
8468ec1109d1 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 14062
diff changeset
   201
    parser.add_option('--extra-config-opt', action="append",
8468ec1109d1 run-tests: add flag to provide extra hgrc options for test runs
Augie Fackler <durin42@gmail.com>
parents: 14062
diff changeset
   202
                      help='set the given config opt in the test hgrc')
19057
3d265e0822d3 run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 18788
diff changeset
   203
    parser.add_option('--random', action="store_true",
3d265e0822d3 run-tests: introduce --random for running tests in random error
Mads Kiilerich <madski@unity3d.com>
parents: 18788
diff changeset
   204
                      help='run tests in random order')
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
   205
14201
57e04ded3da4 run-tests: use type of default to convert environment variable
Martin Geisler <mg@lazybytes.net>
parents: 14192
diff changeset
   206
    for option, (envvar, default) in defaults.items():
57e04ded3da4 run-tests: use type of default to convert environment variable
Martin Geisler <mg@lazybytes.net>
parents: 14192
diff changeset
   207
        defaults[option] = type(default)(os.environ.get(envvar, default))
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   208
    parser.set_defaults(**defaults)
21008
c1dd04be3d9a run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21007
diff changeset
   209
c1dd04be3d9a run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21007
diff changeset
   210
    return parser
c1dd04be3d9a run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21007
diff changeset
   211
c1dd04be3d9a run-tests: allow option parser to be extended
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21007
diff changeset
   212
def parseargs(args, parser):
21383
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   213
    """Parse arguments with our OptionParser and validate results."""
21006
723e41ad59b4 run-tests: Pass arguments into argument parser
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20821
diff changeset
   214
    (options, args) = parser.parse_args(args)
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   215
10758
2ed667a9dfcb tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10750
diff changeset
   216
    # jython is always pure
10766
afbcea270bb8 run-tests: force to test pure on pypy as well
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10765
diff changeset
   217
    if 'java' in sys.platform or '__pypy__' in sys.modules:
10765
fd31a3237498 Fix run-tests.py -jX after 2ed667a9dfcb
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10758
diff changeset
   218
        options.pure = True
10758
2ed667a9dfcb tests: adapt the test runner to work with jython
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10750
diff changeset
   219
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   220
    if options.with_hg:
15942
d7a34c07e69b run-tests: expand user in --with-hg
Mads Kiilerich <mads@kiilerich.com>
parents: 15941
diff changeset
   221
        options.with_hg = os.path.expanduser(options.with_hg)
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   222
        if not (os.path.isfile(options.with_hg) and
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   223
                os.access(options.with_hg, os.X_OK)):
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   224
            parser.error('--with-hg must specify an executable hg script')
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   225
        if not os.path.basename(options.with_hg) == 'hg':
14359
ad5c68a0db6a run-tests: print a newline after all warnings
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14340
diff changeset
   226
            sys.stderr.write('warning: --with-hg should specify an hg script\n')
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   227
    if options.local:
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   228
        testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   229
        hgbin = os.path.join(os.path.dirname(testdir), 'hg')
16538
dd194e5df4c1 tests: don't require 'hg' without extension on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 16346
diff changeset
   230
        if os.name != 'nt' and not os.access(hgbin, os.X_OK):
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   231
            parser.error('--local specified, but %r not found or not executable'
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   232
                         % hgbin)
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   233
        options.with_hg = hgbin
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   234
15859
44a371823f83 tests: add htmlcov option
Markus Zapke-Gründemann <info@keimlink.de>
parents: 15858
diff changeset
   235
    options.anycoverage = options.cover or options.annotate or options.htmlcov
10648
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   236
    if options.anycoverage:
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   237
        try:
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   238
            import coverage
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   239
            covver = version.StrictVersion(coverage.__version__).version
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   240
            if covver < (3, 3):
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   241
                parser.error('coverage options require coverage 3.3 or later')
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   242
        except ImportError:
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   243
            parser.error('coverage options now require the coverage package')
8095
f5428d4ffd97 run-tests: reduce global variables set by parse_args().
Greg Ward <greg-hg@gerg.ca>
parents: 8094
diff changeset
   244
10648
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   245
    if options.anycoverage and options.local:
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   246
        # this needs some path mangling somewhere, I guess
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   247
        parser.error("sorry, coverage options do not work when --local "
58128004cca1 tests: use external coverage, mandate newer version
Dirkjan Ochtman <djc.ochtman@kentyde.com>
parents: 10413
diff changeset
   248
                     "is specified")
8674
0941ee76489e run-tests: redefine --with-hg so it takes the 'hg' script to run.
Greg Ward <greg-hg@gerg.ca>
parents: 8673
diff changeset
   249
19250
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   250
    global verbose
8095
f5428d4ffd97 run-tests: reduce global variables set by parse_args().
Greg Ward <greg-hg@gerg.ca>
parents: 8094
diff changeset
   251
    if options.verbose:
19279
3868c9ab4bf8 run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 19278
diff changeset
   252
        verbose = ''
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   253
9394
31203db1b2ac run-tests: expand --tmpdir and create it if needed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9031
diff changeset
   254
    if options.tmpdir:
31203db1b2ac run-tests: expand --tmpdir and create it if needed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9031
diff changeset
   255
        options.tmpdir = os.path.expanduser(options.tmpdir)
31203db1b2ac run-tests: expand --tmpdir and create it if needed
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9031
diff changeset
   256
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   257
    if options.jobs < 1:
9408
70bf7f853adc run-tests: standardize on --foo instead of -f/--foo
Martin Geisler <mg@lazybytes.net>
parents: 9407
diff changeset
   258
        parser.error('--jobs must be positive')
9707
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   259
    if options.interactive and options.debug:
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   260
        parser.error("-i/--interactive and -d/--debug are incompatible")
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   261
    if options.debug:
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   262
        if options.timeout != defaults['timeout']:
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   263
            sys.stderr.write(
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   264
                'warning: --timeout option ignored with --debug\n')
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   265
        options.timeout = 0
9028
bea567ae3ff6 tests: add -3 switch to run-tests.py
Alejandro Santos <alejolp@alejolp.com>
parents: 8943
diff changeset
   266
    if options.py3k_warnings:
bea567ae3ff6 tests: add -3 switch to run-tests.py
Alejandro Santos <alejolp@alejolp.com>
parents: 8943
diff changeset
   267
        if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
9408
70bf7f853adc run-tests: standardize on --foo instead of -f/--foo
Martin Geisler <mg@lazybytes.net>
parents: 9407
diff changeset
   268
            parser.error('--py3k-warnings can only be used on Python 2.6+')
9959
b37b060d84c7 run-tests: add a "--blacklist target" option to skip predefined test lists
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9958
diff changeset
   269
    if options.blacklist:
14493
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   270
        options.blacklist = parselistfiles(options.blacklist, 'blacklist')
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   271
    if options.whitelist:
19279
3868c9ab4bf8 run-tests: drop options.child and users
Matt Mackall <mpm@selenic.com>
parents: 19278
diff changeset
   272
        options.whitelisted = parselistfiles(options.whitelist, 'whitelist')
14493
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   273
    else:
5cc7905bccc9 run-tests: allow whitelisting tests that should always run
Augie Fackler <durin42@gmail.com>
parents: 14454
diff changeset
   274
        options.whitelisted = {}
8091
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   275
e85cc856d2e1 run-tests: factor out parse_args(). Clarify use of globals a bit.
Greg Ward <greg-hg@gerg.ca>
parents: 8060
diff changeset
   276
    return (options, args)
5384
e3a0c092b4e2 Allow tests to run in parallel.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5383
diff changeset
   277
5800
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   278
def rename(src, dst):
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   279
    """Like os.rename(), trade atomicity and opened files friendliness
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   280
    for existing destination support.
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   281
    """
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   282
    shutil.copy(src, dst)
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   283
    os.remove(src)
2f597243e1d7 Make run-tests.py --interactive work on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5524
diff changeset
   284
10088
ec8304e66ea5 run-tests.py: Show paths to failing tests, .err and .out
Mads Kiilerich <mads@kiilerich.com>
parents: 10030
diff changeset
   285
def showdiff(expected, output, ref, err):
14062
643381286e0c run-tests: print a new line before writing the diff
Idan Kamara <idankk86@gmail.com>
parents: 14037
diff changeset
   286
    print
21022
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   287
    servefail = False
10088
ec8304e66ea5 run-tests.py: Show paths to failing tests, .err and .out
Mads Kiilerich <mads@kiilerich.com>
parents: 10030
diff changeset
   288
    for line in difflib.unified_diff(expected, output, ref, err):
2247
546c76e5a3e6 run-tests.py: fix handling of newlines.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2246
diff changeset
   289
        sys.stdout.write(line)
21022
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   290
        if not servefail and line.startswith(
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   291
                             '+  abort: child process failed to start'):
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   292
            servefail = True
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   293
    return {'servefail': servefail}
52e9e63f1495 run-tests: test result shows when a failed test could not start a server
Simon Heimberg <simohe@besonet.ch>
parents: 21009
diff changeset
   294
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
   295
19250
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   296
verbose = False
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   297
def vlog(*msg):
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   298
    if verbose is not False:
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   299
        iolock.acquire()
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   300
        if verbose:
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   301
            print verbose,
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   302
        for m in msg:
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   303
            print m,
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   304
        print
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   305
        sys.stdout.flush()
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   306
        iolock.release()
5fa946330970 run-tests: make vlog a proper function
Matt Mackall <mpm@selenic.com>
parents: 19249
diff changeset
   307
19251
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   308
def log(*msg):
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   309
    iolock.acquire()
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   310
    if verbose:
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   311
        print verbose,
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   312
    for m in msg:
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   313
        print m,
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   314
    print
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   315
    sys.stdout.flush()
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   316
    iolock.release()
6857f53456f2 run-tests: add a log function
Matt Mackall <mpm@selenic.com>
parents: 19250
diff changeset
   317
14821
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   318
def terminate(proc):
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   319
    """Terminate subprocess (with fallback for Python versions < 2.6)"""
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   320
    vlog('# Terminating process %d' % proc.pid)
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   321
    try:
14971
0b21ae0a2366 tests: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14867
diff changeset
   322
        getattr(proc, 'terminate', lambda : os.kill(proc.pid, signal.SIGTERM))()
14821
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   323
    except OSError:
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   324
        pass
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   325
19263
062c0a0a5549 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 19262
diff changeset
   326
def killdaemons(pidfile):
062c0a0a5549 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 19262
diff changeset
   327
    return killmod.killdaemons(pidfile, tryhard=False, remove=True,
17464
eddfb9a550d0 run-tests: do not duplicate killdaemons() code
Patrick Mezard <patrick@mezard.eu>
parents: 16906
diff changeset
   328
                               logfn=vlog)
10336
bc9a3bb267fa run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 10300
diff changeset
   329
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   330
class Test(object):
21309
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   331
    """Encapsulates a single, runnable test.
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   332
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   333
    Test instances can be run multiple times via run(). However, multiple
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   334
    runs cannot be run concurrently.
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   335
    """
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   336
21380
de6ea36ca9f7 run-tests: move SKIPPED_STATUS into Test class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21379
diff changeset
   337
    # Status code reserved for skipped tests (used by hghave).
de6ea36ca9f7 run-tests: move SKIPPED_STATUS into Test class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21379
diff changeset
   338
    SKIPPED_STATUS = 80
de6ea36ca9f7 run-tests: move SKIPPED_STATUS into Test class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21379
diff changeset
   339
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   340
    def __init__(self, runner, test, count, refpath):
21342
1ad7aabba14e run-tests: move HGTMP out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21341
diff changeset
   341
        path = os.path.join(runner.testdir, test)
1ad7aabba14e run-tests: move HGTMP out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21341
diff changeset
   342
        errpath = os.path.join(runner.testdir, '%s.err' % test)
21338
3cd2d2de4060 run-tests: move computation of test paths into Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21337
diff changeset
   343
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   344
        self.name = test
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   345
21358
fcc2e02e91a2 run-tests: move times global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21357
diff changeset
   346
        self._runner = runner
21342
1ad7aabba14e run-tests: move HGTMP out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21341
diff changeset
   347
        self._testdir = runner.testdir
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   348
        self._path = path
21349
2d767c7c3df0 run-tests: add options to runner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21348
diff changeset
   349
        self._options = runner.options
21309
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   350
        self._count = count
21319
44c96e2bab20 run-tests: kill daemons during Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21318
diff changeset
   351
        self._daemonpids = []
21321
d06b09dc80a5 run-tests: move err path handling to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21320
diff changeset
   352
        self._refpath = refpath
d06b09dc80a5 run-tests: move err path handling to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21320
diff changeset
   353
        self._errpath = errpath
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   354
21447
f8c5b8a288c5 run-tests: keep track of test execution state in Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21446
diff changeset
   355
        self._finished = None
21449
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   356
        self._ret = None
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   357
        self._out = None
21450
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   358
        self._duration = None
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   359
        self._result = None
21453
aaf52b78327e run-tests: store skipped state on Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21452
diff changeset
   360
        self._skipped = None
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   361
        self._testtmp = None
21447
f8c5b8a288c5 run-tests: keep track of test execution state in Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21446
diff changeset
   362
21318
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   363
        # If we're not in --debug mode and reference output file exists,
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   364
        # check test output against it.
21349
2d767c7c3df0 run-tests: add options to runner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21348
diff changeset
   365
        if runner.options.debug:
21318
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   366
            self._refout = None # to match "out is None"
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   367
        elif os.path.exists(refpath):
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   368
            f = open(refpath, 'r')
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   369
            self._refout = f.read().splitlines(True)
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   370
            f.close()
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   371
        else:
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   372
            self._refout = []
6b3d66e4d3be run-tests: capture reference output in Test.__init__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21317
diff changeset
   373
21342
1ad7aabba14e run-tests: move HGTMP out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21341
diff changeset
   374
        self._threadtmp = os.path.join(runner.hgtmp, 'child%d' % count)
21310
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   375
        os.mkdir(self._threadtmp)
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   376
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   377
    def cleanup(self):
21319
44c96e2bab20 run-tests: kill daemons during Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21318
diff changeset
   378
        for entry in self._daemonpids:
44c96e2bab20 run-tests: kill daemons during Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21318
diff changeset
   379
            killdaemons(entry)
44c96e2bab20 run-tests: kill daemons during Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21318
diff changeset
   380
21310
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   381
        if self._threadtmp and not self._options.keep_tmpdir:
21461
a46a91989d57 run-tests: ignore failures from rmtree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21460
diff changeset
   382
            # Ignore failures here. The rmtree() in the higher level runner
a46a91989d57 run-tests: ignore failures from rmtree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21460
diff changeset
   383
            # will try again.
21310
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   384
            shutil.rmtree(self._threadtmp, True)
21304
e626a67da4ba run-tests: clean up temp directory variables
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21303
diff changeset
   385
21463
c908ff887589 run-tests: implement Test.__str__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21462
diff changeset
   386
    def __str__(self):
c908ff887589 run-tests: implement Test.__str__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21462
diff changeset
   387
        return self.name
c908ff887589 run-tests: implement Test.__str__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21462
diff changeset
   388
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   389
    def setUp(self):
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   390
        """Tasks to perform before run()."""
21447
f8c5b8a288c5 run-tests: keep track of test execution state in Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21446
diff changeset
   391
        self._finished = False
21449
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   392
        self._ret = None
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   393
        self._out = None
21450
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   394
        self._duration = None
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   395
        self._result = None
21453
aaf52b78327e run-tests: store skipped state on Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21452
diff changeset
   396
        self._skipped = None
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   397
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   398
        self._testtmp = os.path.join(self._threadtmp,
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   399
                                     os.path.basename(self._path))
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   400
        os.mkdir(self._testtmp)
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   401
21457
12dd94e32102 run-tests: move errpath deletion to setUp()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21456
diff changeset
   402
        # Remove any previous output files.
12dd94e32102 run-tests: move errpath deletion to setUp()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21456
diff changeset
   403
        if os.path.exists(self._errpath):
12dd94e32102 run-tests: move errpath deletion to setUp()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21456
diff changeset
   404
            os.remove(self._errpath)
12dd94e32102 run-tests: move errpath deletion to setUp()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21456
diff changeset
   405
21336
45ab0668d1b2 run-tests: remove remaining uses of TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21335
diff changeset
   406
    def run(self):
21383
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   407
        """Run this test instance.
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   408
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   409
        This will return a tuple describing the result of the test.
772ed56e2519 run-tests: add some docstrings
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21382
diff changeset
   410
        """
21328
9da0761a22a1 run-tests: check for test file existence in Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21327
diff changeset
   411
        if not os.path.exists(self._path):
9da0761a22a1 run-tests: check for test file existence in Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21327
diff changeset
   412
            return self.skip("Doesn't exist")
9da0761a22a1 run-tests: check for test file existence in Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21327
diff changeset
   413
21329
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   414
        options = self._options
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   415
        if not (options.whitelisted and self.name in options.whitelisted):
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   416
            if options.blacklist and self.name in options.blacklist:
21329
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   417
                return self.skip('blacklisted')
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   418
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   419
            if options.retest and not os.path.exists('%s.err' % self.name):
21330
3f79bacbf80b run-tests: move retesting result to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21329
diff changeset
   420
                return self.ignore('not retesting')
3f79bacbf80b run-tests: move retesting result to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21329
diff changeset
   421
21331
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   422
            if options.keywords:
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   423
                f = open(self.name)
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   424
                t = f.read().lower() + self.name.lower()
21331
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   425
                f.close()
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   426
                for k in options.keywords.lower().split():
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   427
                    if k in t:
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   428
                        break
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   429
                    else:
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   430
                        return self.ignore("doesn't match keyword")
bfe929a4b45b run-tests: move keyword processing into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21330
diff changeset
   431
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   432
        if not os.path.basename(self.name.lower()).startswith('test-'):
21332
60ce874f5b06 run-tests: move test name filter to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21331
diff changeset
   433
            return self.skip('not a test file')
60ce874f5b06 run-tests: move test name filter to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21331
diff changeset
   434
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   435
        replacements, port = self._getreplacements()
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   436
        env = self._getenv(port)
21319
44c96e2bab20 run-tests: kill daemons during Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21318
diff changeset
   437
        self._daemonpids.append(env['DAEMON_PIDS'])
21382
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   438
        self._createhgrc(env['HGRCPATH'])
21300
a2774731a51a run-tests: move createhgrc() call into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21299
diff changeset
   439
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   440
        vlog('# Test', self.name)
21337
79930515604f run-tests: move logging of test start into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21336
diff changeset
   441
21305
d7a7825ff2cf run-tests: capture execution results in a TestResult class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21304
diff changeset
   442
        starttime = time.time()
21302
9e5d8eaa4a20 run-tests: move killdaemons into Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21301
diff changeset
   443
        try:
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   444
            ret, out = self._run(replacements, env)
21450
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   445
            self._duration = time.time() - starttime
21447
f8c5b8a288c5 run-tests: keep track of test execution state in Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21446
diff changeset
   446
            self._finished = True
21449
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   447
            self._ret = ret
aedf18bcde11 run-tests: store test return code and output in Test instance
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21448
diff changeset
   448
            self._out = out
21305
d7a7825ff2cf run-tests: capture execution results in a TestResult class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21304
diff changeset
   449
        except KeyboardInterrupt:
21450
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   450
            self._duration = time.time() - starttime
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   451
            log('INTERRUPTED: %s (after %d seconds)' % (self.name,
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   452
                                                        self._duration))
21320
e5eed8ded168 run-tests: handle interrupted in Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21319
diff changeset
   453
            raise
21305
d7a7825ff2cf run-tests: capture execution results in a TestResult class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21304
diff changeset
   454
        except Exception, e:
21333
9a5913beaf77 run-tests: emit exception failure result from Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21332
diff changeset
   455
            return self.fail('Exception during execution: %s' % e, 255)
21305
d7a7825ff2cf run-tests: capture execution results in a TestResult class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21304
diff changeset
   456
21326
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   457
        def describe(ret):
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   458
            if ret < 0:
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   459
                return 'killed by signal: %d' % -ret
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   460
            return 'returned error code %d' % ret
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   461
21453
aaf52b78327e run-tests: store skipped state on Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21452
diff changeset
   462
        self._skipped = False
21336
45ab0668d1b2 run-tests: remove remaining uses of TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21335
diff changeset
   463
21380
de6ea36ca9f7 run-tests: move SKIPPED_STATUS into Test class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21379
diff changeset
   464
        if ret == self.SKIPPED_STATUS:
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   465
            if out is None: # Debug mode, nothing to parse.
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   466
                missing = ['unknown']
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   467
                failed = None
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   468
            else:
21379
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   469
                missing, failed = TTest.parsehghaveoutput(out)
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   470
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   471
            if not missing:
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   472
                missing = ['irrelevant']
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   473
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   474
            if failed:
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   475
                self._result = self.fail('hg have failed checking for %s' %
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   476
                                         failed[-1], ret)
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   477
            else:
21453
aaf52b78327e run-tests: store skipped state on Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21452
diff changeset
   478
                self._skipped = True
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   479
                self._result = self.skip(missing[-1])
21325
0e66eb57e42a run-tests: generate timeout result in Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21324
diff changeset
   480
        elif ret == 'timeout':
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   481
            self._result = self.fail('timed out', ret)
21326
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   482
        elif out != self._refout:
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   483
            info = {}
21329
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   484
            if not options.nodiff:
21326
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   485
                iolock.acquire()
21329
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   486
                if options.view:
8ead79ffbc40 run-tests: move blacklist skipping to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21328
diff changeset
   487
                    os.system("%s %s %s" % (options.view, self._refpath,
21326
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   488
                                            self._errpath))
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   489
                else:
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   490
                    info = showdiff(self._refout, out, self._refpath,
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   491
                                    self._errpath)
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   492
                iolock.release()
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   493
            msg = ''
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   494
            if info.get('servefail'):
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   495
                msg += 'serve failed and '
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   496
            if ret:
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   497
                msg += 'output changed and ' + describe(ret)
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   498
            else:
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   499
                msg += 'output changed'
04e04766065f run-tests: move output difference processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21325
diff changeset
   500
21453
aaf52b78327e run-tests: store skipped state on Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21452
diff changeset
   501
            if (ret != 0 or out != self._refout) and not self._skipped \
21386
3b0c522f04aa run-test: restore the -i prompt by write .err before checking if it exists
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21385
diff changeset
   502
                and not options.debug:
3b0c522f04aa run-test: restore the -i prompt by write .err before checking if it exists
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21385
diff changeset
   503
                f = open(self._errpath, 'wb')
3b0c522f04aa run-test: restore the -i prompt by write .err before checking if it exists
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21385
diff changeset
   504
                for line in out:
3b0c522f04aa run-test: restore the -i prompt by write .err before checking if it exists
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21385
diff changeset
   505
                    f.write(line)
3b0c522f04aa run-test: restore the -i prompt by write .err before checking if it exists
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21385
diff changeset
   506
            f.close()
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   507
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   508
            self._result = self.fail(msg, ret)
21327
206814c9072a run-tests: move remaining result processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21326
diff changeset
   509
        elif ret:
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   510
            self._result = self.fail(describe(ret), ret)
21327
206814c9072a run-tests: move remaining result processing to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21326
diff changeset
   511
        else:
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   512
            self._result = self.success()
21334
6a90ecb6597a run-tests: move err file saving to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21333
diff changeset
   513
21451
1b3a1ebdcfee run-tests: store last result in Test._result
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21450
diff changeset
   514
        return self._result
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   515
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   516
    def tearDown(self):
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   517
        """Tasks to perform after run()."""
21456
a06a4142ad1f run-tests: kill daemons during tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21455
diff changeset
   518
        for entry in self._daemonpids:
a06a4142ad1f run-tests: kill daemons during tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21455
diff changeset
   519
            killdaemons(entry)
a06a4142ad1f run-tests: kill daemons during tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21455
diff changeset
   520
        self._daemonpids = []
a06a4142ad1f run-tests: kill daemons during tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21455
diff changeset
   521
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   522
        if not self._options.keep_tmpdir:
21461
a46a91989d57 run-tests: ignore failures from rmtree
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21460
diff changeset
   523
            shutil.rmtree(self._testtmp, True)
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   524
21455
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   525
        if (self._ret != 0 or self._out != self._refout) and not self._skipped \
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   526
            and not self._options.debug and self._out:
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   527
            f = open(self._errpath, 'wb')
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   528
            for line in self._out:
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   529
                f.write(line)
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   530
            f.close()
0f0bace82149 run-tests: move err file writing to tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21454
diff changeset
   531
21452
1517c0461b75 run-tests: move some functionality to Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21451
diff changeset
   532
        vlog("# Ret was:", self._ret)
1517c0461b75 run-tests: move some functionality to Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21451
diff changeset
   533
21450
a6e40416f172 run-tests: report test duration in Test.tearDown()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21449
diff changeset
   534
        self._runner.times.append((self.name, self._duration))
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
   535
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   536
    def _run(self, replacements, env):
21339
de25e968b4d8 run-tests: refactor runone() into gettest() and scheduletests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21338
diff changeset
   537
        # This should be implemented in child classes to run tests.
de25e968b4d8 run-tests: refactor runone() into gettest() and scheduletests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21338
diff changeset
   538
        return self._skip('unknown test type')
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   539
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   540
    def _getreplacements(self):
21309
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   541
        port = self._options.port + self._count * 3
21298
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   542
        r = [
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   543
            (r':%s\b' % port, ':$HGPORT'),
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   544
            (r':%s\b' % (port + 1), ':$HGPORT1'),
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   545
            (r':%s\b' % (port + 2), ':$HGPORT2'),
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   546
            ]
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   547
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   548
        if os.name == 'nt':
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   549
            r.append(
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   550
                (''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   551
                    c in '/\\' and r'[/\\]' or c.isdigit() and c or '\\' + c
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   552
                    for c in self._testtmp), '$TESTTMP'))
21298
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   553
        else:
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   554
            r.append((re.escape(self._testtmp), '$TESTTMP'))
21298
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   555
21309
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   556
        return r, port
21298
ba4750352180 run-tests: move replacements generation into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21297
diff changeset
   557
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   558
    def _getenv(self, port):
21299
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   559
        env = os.environ.copy()
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   560
        env['TESTTMP'] = self._testtmp
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   561
        env['HOME'] = self._testtmp
21309
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   562
        env["HGPORT"] = str(port)
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   563
        env["HGPORT1"] = str(port + 1)
0b123e6a318c run-tests: allow Test.run() to run multiple times
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21308
diff changeset
   564
        env["HGPORT2"] = str(port + 2)
21310
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   565
        env["HGRCPATH"] = os.path.join(self._threadtmp, '.hgrc')
af9a04951c69 run-tests: remove threadtmp in Test.cleanup()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21309
diff changeset
   566
        env["DAEMON_PIDS"] = os.path.join(self._threadtmp, 'daemon.pids')
21299
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   567
        env["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   568
        env["HGMERGE"] = "internal:merge"
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   569
        env["HGUSER"]   = "test"
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   570
        env["HGENCODING"] = "ascii"
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   571
        env["HGENCODINGMODE"] = "strict"
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   572
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   573
        # Reset some environment variables to well-known values so that
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   574
        # the tests produce repeatable output.
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   575
        env['LANG'] = env['LC_ALL'] = env['LANGUAGE'] = 'C'
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   576
        env['TZ'] = 'GMT'
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   577
        env["EMAIL"] = "Foo Bar <foo.bar@example.com>"
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   578
        env['COLUMNS'] = '80'
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   579
        env['TERM'] = 'xterm'
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   580
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   581
        for k in ('HG HGPROF CDPATH GREP_OPTIONS http_proxy no_proxy ' +
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   582
                  'NO_PROXY').split():
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   583
            if k in env:
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   584
                del env[k]
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   585
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   586
        # unset env related to hooks
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   587
        for k in env.keys():
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   588
            if k.startswith('HG_'):
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   589
                del env[k]
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   590
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   591
        return env
7861de61583b run-tests: move createenv() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21298
diff changeset
   592
21382
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   593
    def _createhgrc(self, path):
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   594
        # create a fresh hgrc
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   595
        hgrc = open(path, 'w')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   596
        hgrc.write('[ui]\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   597
        hgrc.write('slash = True\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   598
        hgrc.write('interactive = False\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   599
        hgrc.write('[defaults]\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   600
        hgrc.write('backout = -d "0 0"\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   601
        hgrc.write('commit = -d "0 0"\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   602
        hgrc.write('shelve = --date "0 0"\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   603
        hgrc.write('tag = -d "0 0"\n')
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   604
        if self._options.extra_config_opt:
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   605
            for opt in self._options.extra_config_opt:
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   606
                section, key = opt.split('.', 1)
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   607
                assert '=' in key, ('extra config opt %s must '
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   608
                                    'have an = for assignment' % opt)
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   609
                hgrc.write('[%s]\n%s\n' % (section, key))
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   610
        hgrc.close()
4b8ffe3abdd2 run-tests: move createhgrc into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21381
diff changeset
   611
21322
512968bfb00a run-tests: move success() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21321
diff changeset
   612
    def success(self):
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   613
        return '.', self.name, ''
21322
512968bfb00a run-tests: move success() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21321
diff changeset
   614
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   615
    def fail(self, msg, ret):
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   616
        warned = ret is False
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   617
        if not self._options.nodiff:
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   618
            log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name,
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   619
                                 msg))
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   620
        if (not ret and self._options.interactive and
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   621
            os.path.exists(self._errpath)):
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   622
            iolock.acquire()
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   623
            print 'Accept this change? [n] ',
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   624
            answer = sys.stdin.readline().strip()
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   625
            iolock.release()
21387
82f8d4e95c87 run-test: fix AttributeError in the --interactive prompt
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21386
diff changeset
   626
            if answer.lower() in ('y', 'yes'):
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   627
                if self.name.endswith('.t'):
21388
9a1e3d705c2c run-tests: fix --interactive option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21387
diff changeset
   628
                    rename(self._errpath, self._path)
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   629
                else:
21388
9a1e3d705c2c run-tests: fix --interactive option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21387
diff changeset
   630
                    rename(self._errpath, '%s.out' % self._path)
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   631
21435
f376f56a354e run-tests: rename Test._test to Test.name
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21434
diff changeset
   632
                return '.', self.name, ''
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   633
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   634
        if warned:
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   635
            raise WarnTest(msg)
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   636
        else:
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   637
            # unittest differentiates between errored and failed.
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   638
            # Failed is denoted by AssertionError (by default at least).
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   639
            raise AssertionError(msg)
21323
a7c677e2f6ae run-tests: move fail() into Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21322
diff changeset
   640
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   641
    def skip(self, msg):
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   642
        raise SkipTest(msg)
21324
6454ddaee991 run-tests: add skip processing to Test
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21323
diff changeset
   643
21330
3f79bacbf80b run-tests: move retesting result to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21329
diff changeset
   644
    def ignore(self, msg):
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
   645
        raise IgnoreTest(msg)
21330
3f79bacbf80b run-tests: move retesting result to Test.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21329
diff changeset
   646
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   647
class PythonTest(Test):
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   648
    """A Python-based test."""
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   649
    def _run(self, replacements, env):
21311
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   650
        py3kswitch = self._options.py3k_warnings and ' -3' or ''
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   651
        cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self._path)
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   652
        vlog("# Running", cmd)
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   653
        if os.name == 'nt':
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   654
            replacements.append((r'\r\n', '\n'))
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   655
        return run(cmd, self._testtmp, self._options, replacements, env,
21361
0fdf92500012 run-tests: move abort global to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21360
diff changeset
   656
                   self._runner.abort)
21311
f9a7018a35ff run-tests: roll pytest() into PythonTest._run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21310
diff changeset
   657
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   658
class TTest(Test):
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   659
    """A "t test" is a test backed by a .t file."""
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   660
21381
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   661
    SKIPPED_PREFIX = 'skipped: '
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   662
    FAILED_PREFIX = 'hghave check failed: '
21384
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   663
    NEEDESCAPE = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   664
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   665
    ESCAPESUB = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   666
    ESCAPEMAP = dict((chr(i), r'\x%02x' % i) for i in range(256)).update(
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   667
                     {'\\': '\\\\', '\r': r'\r'})
21381
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   668
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   669
    def _run(self, replacements, env):
21313
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   670
        f = open(self._path)
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   671
        lines = f.readlines()
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   672
        f.close()
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   673
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   674
        salt, script, after, expected = self._parsetest(lines)
21313
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   675
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   676
        # Write out the generated script.
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   677
        fname = '%s.sh' % self._testtmp
21313
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   678
        f = open(fname, 'w')
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   679
        for l in script:
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   680
            f.write(l)
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   681
        f.close()
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   682
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   683
        cmd = '%s "%s"' % (self._options.shell, fname)
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   684
        vlog("# Running", cmd)
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   685
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   686
        exitcode, output = run(cmd, self._testtmp, self._options, replacements,
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   687
                               env, self._runner.abort)
21313
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   688
        # Do not merge output if skipped. Return hghave message instead.
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   689
        # Similarly, with --debug, output is None.
21380
de6ea36ca9f7 run-tests: move SKIPPED_STATUS into Test class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21379
diff changeset
   690
        if exitcode == self.SKIPPED_STATUS or output is None:
21313
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   691
            return exitcode, output
a2bd02a3b6d2 run-tests: move t test execution from tsttest() to TTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21312
diff changeset
   692
21314
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   693
        return self._processoutput(exitcode, output, salt, after, expected)
21296
cd8776030833 run-tests: create classes for representing tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21231
diff changeset
   694
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   695
    def _hghave(self, reqs):
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   696
        # TODO do something smarter when all other uses of hghave are gone.
21341
cb88d4a04f58 run-tests: move TESTDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21340
diff changeset
   697
        tdir = self._testdir.replace('\\', '/')
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   698
        proc = Popen4('%s -c "%s/hghave %s"' %
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   699
                      (self._options.shell, tdir, ' '.join(reqs)),
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   700
                      self._testtmp, 0)
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   701
        stdout, stderr = proc.communicate()
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   702
        ret = proc.wait()
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   703
        if wifexited(ret):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   704
            ret = os.WEXITSTATUS(ret)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   705
        if ret == 2:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   706
            print stdout
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   707
            sys.exit(1)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   708
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   709
        return ret == 0
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   710
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   711
    def _parsetest(self, lines):
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   712
        # We generate a shell script which outputs unique markers to line
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   713
        # up script results with our source. These markers include input
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   714
        # line number and the last return code.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   715
        salt = "SALT" + str(time.time())
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   716
        def addsalt(line, inpython):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   717
            if inpython:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   718
                script.append('%s %d 0\n' % (salt, line))
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   719
            else:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   720
                script.append('echo %s %s $?\n' % (salt, line))
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   721
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   722
        script = []
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   723
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   724
        # After we run the shell script, we re-unify the script output
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   725
        # with non-active parts of the source, with synchronization by our
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   726
        # SALT line number markers. The after table contains the non-active
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   727
        # components, ordered by line number.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   728
        after = {}
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   729
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   730
        # Expected shell script output.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   731
        expected = {}
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   732
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   733
        pos = prepos = -1
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   734
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   735
        # True or False when in a true or false conditional section
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   736
        skipping = None
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   737
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   738
        # We keep track of whether or not we're in a Python block so we
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   739
        # can generate the surrounding doctest magic.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   740
        inpython = False
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   741
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   742
        if self._options.debug:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   743
            script.append('set -x\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   744
        if os.getenv('MSYSTEM'):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   745
            script.append('alias pwd="pwd -W"\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   746
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   747
        for n, l in enumerate(lines):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   748
            if not l.endswith('\n'):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   749
                l += '\n'
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   750
            if l.startswith('#if'):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   751
                lsplit = l.split()
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   752
                if len(lsplit) < 2 or lsplit[0] != '#if':
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   753
                    after.setdefault(pos, []).append('  !!! invalid #if\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   754
                if skipping is not None:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   755
                    after.setdefault(pos, []).append('  !!! nested #if\n')
21454
046587aa1c8a run-tests: refactor testtmp
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21453
diff changeset
   756
                skipping = not self._hghave(lsplit[1:])
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   757
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   758
            elif l.startswith('#else'):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   759
                if skipping is None:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   760
                    after.setdefault(pos, []).append('  !!! missing #if\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   761
                skipping = not skipping
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   762
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   763
            elif l.startswith('#endif'):
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   764
                if skipping is None:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   765
                    after.setdefault(pos, []).append('  !!! missing #if\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   766
                skipping = None
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   767
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   768
            elif skipping:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   769
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   770
            elif l.startswith('  >>> '): # python inlines
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   771
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   772
                prepos = pos
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   773
                pos = n
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   774
                if not inpython:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   775
                    # We've just entered a Python block. Add the header.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   776
                    inpython = True
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   777
                    addsalt(prepos, False) # Make sure we report the exit code.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   778
                    script.append('%s -m heredoctest <<EOF\n' % PYTHON)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   779
                addsalt(n, True)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   780
                script.append(l[2:])
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   781
            elif l.startswith('  ... '): # python inlines
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   782
                after.setdefault(prepos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   783
                script.append(l[2:])
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   784
            elif l.startswith('  $ '): # commands
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   785
                if inpython:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   786
                    script.append('EOF\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   787
                    inpython = False
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   788
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   789
                prepos = pos
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   790
                pos = n
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   791
                addsalt(n, False)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   792
                cmd = l[4:].split()
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   793
                if len(cmd) == 2 and cmd[0] == 'cd':
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   794
                    l = '  $ cd %s || exit 1\n' % cmd[1]
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   795
                script.append(l[4:])
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   796
            elif l.startswith('  > '): # continuations
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   797
                after.setdefault(prepos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   798
                script.append(l[4:])
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   799
            elif l.startswith('  '): # results
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   800
                # Queue up a list of expected results.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   801
                expected.setdefault(pos, []).append(l[2:])
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   802
            else:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   803
                if inpython:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   804
                    script.append('EOF\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   805
                    inpython = False
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   806
                # Non-command/result. Queue up for merged output.
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   807
                after.setdefault(pos, []).append(l)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   808
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   809
        if inpython:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   810
            script.append('EOF\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   811
        if skipping is not None:
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   812
            after.setdefault(pos, []).append('  !!! missing #endif\n')
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   813
        addsalt(n + 1, False)
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   814
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   815
        return salt, script, after, expected
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   816
21314
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   817
    def _processoutput(self, exitcode, output, salt, after, expected):
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   818
        # Merge the script output back into a unified test.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   819
        warnonly = 1 # 1: not yet; 2: yes; 3: for sure not
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   820
        if exitcode != 0:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   821
            warnonly = 3
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   822
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   823
        pos = -1
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   824
        postout = []
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   825
        for l in output:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   826
            lout, lcmd = l, None
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   827
            if salt in l:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   828
                lout, lcmd = l.split(salt, 1)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   829
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   830
            if lout:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   831
                if not lout.endswith('\n'):
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   832
                    lout += ' (no-eol)\n'
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   833
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   834
                # Find the expected output at the current position.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   835
                el = None
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   836
                if expected.get(pos, None):
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   837
                    el = expected[pos].pop(0)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   838
21315
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   839
                r = TTest.linematch(el, lout)
21314
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   840
                if isinstance(r, str):
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   841
                    if r == '+glob':
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   842
                        lout = el[:-1] + ' (glob)\n'
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   843
                        r = '' # Warn only this line.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   844
                    elif r == '-glob':
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   845
                        lout = ''.join(el.rsplit(' (glob)', 1))
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   846
                        r = '' # Warn only this line.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   847
                    else:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   848
                        log('\ninfo, unknown linematch result: %r\n' % r)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   849
                        r = False
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   850
                if r:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   851
                    postout.append('  ' + el)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   852
                else:
21384
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   853
                    if self.NEEDESCAPE(lout):
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   854
                        lout = TTest.stringescape('%s (esc)\n' %
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   855
                                                  lout.rstrip('\n'))
21314
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   856
                    postout.append('  ' + lout) # Let diff deal with it.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   857
                    if r != '': # If line failed.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   858
                        warnonly = 3 # for sure not
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   859
                    elif warnonly == 1: # Is "not yet" and line is warn only.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   860
                        warnonly = 2 # Yes do warn.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   861
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   862
            if lcmd:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   863
                # Add on last return code.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   864
                ret = int(lcmd.split()[1])
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   865
                if ret != 0:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   866
                    postout.append('  [%s]\n' % ret)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   867
                if pos in after:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   868
                    # Merge in non-active test bits.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   869
                    postout += after.pop(pos)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   870
                pos = int(lcmd.split()[0])
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   871
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   872
        if pos in after:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   873
            postout += after.pop(pos)
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   874
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   875
        if warnonly == 2:
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   876
            exitcode = False # Set exitcode to warned.
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   877
76d7967d8f3d run-tests: finish moving tsttest() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21313
diff changeset
   878
        return exitcode, postout
21312
986b8a58a6d3 run-tests: move t test parsing into its own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21311
diff changeset
   879
21315
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   880
    @staticmethod
21316
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   881
    def rematch(el, l):
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   882
        try:
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   883
            # use \Z to ensure that the regex matches to the end of the string
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   884
            if os.name == 'nt':
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   885
                return re.match(el + r'\r?\n\Z', l)
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   886
            return re.match(el + r'\n\Z', l)
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   887
        except re.error:
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   888
            # el is an invalid regex
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   889
            return False
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   890
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   891
    @staticmethod
21317
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   892
    def globmatch(el, l):
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   893
        # The only supported special characters are * and ? plus / which also
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   894
        # matches \ on windows. Escaping of these characters is supported.
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   895
        if el + '\n' == l:
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   896
            if os.altsep:
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   897
                # matching on "/" is not needed for this line
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   898
                return '-glob'
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   899
            return True
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   900
        i, n = 0, len(el)
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   901
        res = ''
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   902
        while i < n:
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   903
            c = el[i]
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   904
            i += 1
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   905
            if c == '\\' and el[i] in '*?\\/':
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   906
                res += el[i - 1:i + 1]
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   907
                i += 1
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   908
            elif c == '*':
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   909
                res += '.*'
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   910
            elif c == '?':
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   911
                res += '.'
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   912
            elif c == '/' and os.altsep:
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   913
                res += '[/\\\\]'
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   914
            else:
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   915
                res += re.escape(c)
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   916
        return TTest.rematch(res, l)
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   917
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   918
    @staticmethod
21315
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   919
    def linematch(el, l):
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   920
        if el == l: # perfect match (fast)
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   921
            return True
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   922
        if el:
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   923
            if el.endswith(" (esc)\n"):
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   924
                el = el[:-7].decode('string-escape') + '\n'
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   925
            if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l:
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   926
                return True
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   927
            if el.endswith(" (re)\n"):
21316
ab9bf8a5e573 run-tests: make rematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21315
diff changeset
   928
                return TTest.rematch(el[:-6], l)
21315
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   929
            if el.endswith(" (glob)\n"):
21317
58a599784a0c run-tests: make globmatch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21316
diff changeset
   930
                return TTest.globmatch(el[:-8], l)
21315
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   931
            if os.altsep and l.replace('\\', '/') == el:
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   932
                return '+glob'
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   933
        return False
56610da39b48 run-tests: make linematch a static method of TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21314
diff changeset
   934
21379
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   935
    @staticmethod
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   936
    def parsehghaveoutput(lines):
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   937
        '''Parse hghave log lines.
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   938
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   939
        Return tuple of lists (missing, failed):
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   940
          * the missing/unknown features
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   941
          * the features for which existence check failed'''
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   942
        missing = []
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   943
        failed = []
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   944
        for line in lines:
21381
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   945
            if line.startswith(TTest.SKIPPED_PREFIX):
21379
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   946
                line = line.splitlines()[0]
21381
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   947
                missing.append(line[len(TTest.SKIPPED_PREFIX):])
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   948
            elif line.startswith(TTest.FAILED_PREFIX):
21379
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   949
                line = line.splitlines()[0]
21381
9aa5784992d4 run-tests: move SKIPPED_PREFIX and FAILED_PREFIX into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21380
diff changeset
   950
                failed.append(line[len(TTest.FAILED_PREFIX):])
21379
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   951
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   952
        return missing, failed
ab1a95270a50 run-tests: move parsehghaveoutput() into TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21378
diff changeset
   953
21384
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   954
    @staticmethod
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   955
    def _escapef(m):
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   956
        return TTest.ESCAPEMAP[m.group(0)]
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   957
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   958
    @staticmethod
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   959
    def _stringescape(s):
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   960
        return TTest.ESCAPESUB(TTest._escapef, s)
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   961
a36cc85a5b7b run-tests: move string escaping to TTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21383
diff changeset
   962
13348
31fdb04cb5e8 run-tests: only call WIFEXITED on systems it exists
Simon Heimberg <simohe@besonet.ch>
parents: 13347
diff changeset
   963
wifexited = getattr(os, "WIFEXITED", lambda x: False)
21361
0fdf92500012 run-tests: move abort global to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21360
diff changeset
   964
def run(cmd, wd, options, replacements, env, abort):
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
   965
    """Run command in a sub-process, capturing the output (stdout and stderr).
9707
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   966
    Return a tuple (exitcode, output).  output is None in debug mode."""
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
   967
    # TODO: Use subprocess.Popen if we're running on Python 2.4
9707
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   968
    if options.debug:
19262
7864e8f274fe run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 19252
diff changeset
   969
        proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env)
9707
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   970
        ret = proc.wait()
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   971
        return (ret, None)
38deec407f8d run-tests: add "debug" mode: don't capture child output, just show it.
Greg Ward <greg-hg@gerg.ca>
parents: 9706
diff changeset
   972
19262
7864e8f274fe run-tests: add env dict to isolate test environment
Matt Mackall <mpm@selenic.com>
parents: 19252
diff changeset
   973
    proc = Popen4(cmd, wd, options.timeout, env)
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   974
    def cleanup():
14821
2017495bd552 run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14598
diff changeset
   975
        terminate(proc)
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   976
        ret = proc.wait()
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   977
        if ret == 0:
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   978
            ret = signal.SIGTERM << 8
19263
062c0a0a5549 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 19262
diff changeset
   979
        killdaemons(env['DAEMON_PIDS'])
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   980
        return ret
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   981
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   982
    output = ''
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   983
    proc.tochild.close()
10336
bc9a3bb267fa run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 10300
diff changeset
   984
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   985
    try:
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   986
        output = proc.fromchild.read()
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   987
    except KeyboardInterrupt:
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   988
        vlog('# Handling keyboard interrupt')
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   989
        cleanup()
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   990
        raise
10336
bc9a3bb267fa run-tests: kill daemons on ^C with -j.
Brendan Cully <brendan@kublai.com>
parents: 10300
diff changeset
   991
19413
a4de0d3dc35a run-tests: lock popen wait/poll
Brendan Cully <brendan@kublai.com>
parents: 19407
diff changeset
   992
    ret = proc.wait()
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   993
    if wifexited(ret):
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   994
        ret = os.WEXITSTATUS(ret)
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
   995
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   996
    if proc.timeout:
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   997
        ret = 'timeout'
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
   998
14338
862f8cd87546 run-tests: use the common test path on Windows and Java
Patrick Mezard <pmezard@gmail.com>
parents: 14337
diff changeset
   999
    if ret:
19263
062c0a0a5549 run-tests: use env dict to kill daemons
Matt Mackall <mpm@selenic.com>
parents: 19262
diff changeset
  1000
        killdaemons(env['DAEMON_PIDS'])
14001
9c4da6ab4e5a run-tests: switch timeout handling from alarm to helper thread
Matt Mackall <mpm@selenic.com>
parents: 14000
diff changeset
  1001
21361
0fdf92500012 run-tests: move abort global to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21360
diff changeset
  1002
    if abort[0]:
19273
f3effc499288 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 19272
diff changeset
  1003
        raise KeyboardInterrupt()
f3effc499288 run-tests: add abort flag
Matt Mackall <mpm@selenic.com>
parents: 19272
diff changeset
  1004
12639
236058a65cb4 tests: replace test tmp directory with $TESTTMP in test output
Mads Kiilerich <mads@kiilerich.com>
parents: 12621
diff changeset
  1005
    for s, r in replacements:
12895
53cfde2b3cf9 run-tests: use regex when searching for $HGPORT in test output
Martin Geisler <mg@aragost.com>
parents: 12721
diff changeset
  1006
        output = re.sub(s, r, output)
17742
405b6bd015df run-tests: allow test output lines to be terminated with \r in addition to \n
Mads Kiilerich <mads@kiilerich.com>
parents: 17741
diff changeset
  1007
    return ret, output.splitlines(True)
2110
25a8d116ab6a Add a pure python version of run-tests.
Stephen Darnell <stephen@darnell.plus.com>
parents:
diff changeset
  1008
14002
a738c30d4b18 run-tests: add a lock for console I/O
Matt Mackall <mpm@selenic.com>
parents: 14001
diff changeset
  1009
iolock = threading.Lock()
14000
636a6f5aa2cd run-tests: add locking on results struct
Matt Mackall <mpm@selenic.com>
parents: 13999
diff changeset
  1010
21442
867a1116be3c run-tests: record skips by raising SkipTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21441
diff changeset
  1011
class SkipTest(Exception):
867a1116be3c run-tests: record skips by raising SkipTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21441
diff changeset
  1012
    """Raised to indicate that a test is to be skipped."""
867a1116be3c run-tests: record skips by raising SkipTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21441
diff changeset
  1013
21443
a6845a042d46 run-tests: record ignored tests by raising IgnoreTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21442
diff changeset
  1014
class IgnoreTest(Exception):
a6845a042d46 run-tests: record ignored tests by raising IgnoreTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21442
diff changeset
  1015
    """Raised to indicate that a test is to be ignored."""
a6845a042d46 run-tests: record ignored tests by raising IgnoreTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21442
diff changeset
  1016
21444
2b7d364690d8 run-tests: record warnings by raising WarnTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21443
diff changeset
  1017
class WarnTest(Exception):
2b7d364690d8 run-tests: record warnings by raising WarnTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21443
diff changeset
  1018
    """Raised to indicate that a test warned."""
2b7d364690d8 run-tests: record warnings by raising WarnTest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21443
diff changeset
  1019
21429
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1020
class TestResult(unittest._TextTestResult):
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1021
    """Holds results when executing via unittest."""
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1022
    # Don't worry too much about accessing the non-public _TextTestResult.
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1023
    # It is relatively common in Python testing tools.
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1024
    def __init__(self, options, *args, **kwargs):
21429
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1025
        super(TestResult, self).__init__(*args, **kwargs)
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1026
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1027
        self._options = options
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1028
21430
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1029
        # unittest.TestResult didn't have skipped until 2.7. We need to
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1030
        # polyfill it.
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1031
        self.skipped = []
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1032
21431
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1033
        # We have a custom "ignored" result that isn't present in any Python
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1034
        # unittest implementation. It is very similar to skipped. It may make
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1035
        # sense to map it into skip some day.
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1036
        self.ignored = []
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1037
21433
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1038
        # We have a custom "warned" result that isn't present in any Python
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1039
        # unittest implementation. It is very similar to failed. It may make
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1040
        # sense to map it into fail some day.
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1041
        self.warned = []
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1042
21462
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1043
    def addFailure(self, test, reason):
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1044
        self.failures.append((test, reason))
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1045
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1046
        if self._options.first:
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1047
            self.stop()
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1048
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1049
    def addError(self, *args, **kwargs):
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1050
        super(TestResult, self).addError(*args, **kwargs)
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1051
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1052
        if self._options.first:
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1053
            self.stop()
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1054
21430
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1055
    # Polyfill.
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1056
    def addSkip(self, test, reason):
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1057
        self.skipped.append((test, reason))
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1058
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1059
        if self.showAll:
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1060
            self.stream.writeln('skipped %s' % reason)
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1061
        else:
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1062
            self.stream.write('s')
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1063
            self.stream.flush()
cf2992656bf8 run-tests: teach unittest about skipped tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21429
diff changeset
  1064
21431
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1065
    def addIgnore(self, test, reason):
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1066
        self.ignored.append((test, reason))
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1067
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1068
        if self.showAll:
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1069
            self.stream.writeln('ignored %s' % reason)
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1070
        else:
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1071
            self.stream.write('i')
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1072
            self.stream.flush()
0f12bc8aed80 run-tests: teach unittest about ignored tests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21430
diff changeset
  1073
21433
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1074
    def addWarn(self, test, reason):
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1075
        self.warned.append((test, reason))
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1076
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1077
        if self._options.first:
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1078
            self.stop()
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1079
21433
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1080
        if self.showAll:
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1081
            self.stream.writeln('warned %s' % reason)
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1082
        else:
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1083
            self.stream.write('~')
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1084
            self.stream.flush()
ff4a270bd334 run-tests: teach unittest about warned results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21432
diff changeset
  1085
21439
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1086
class TestSuite(unittest.TestSuite):
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1087
    """Custom unitest TestSuite that knows how to execute concurrently."""
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1088
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1089
    def __init__(self, runner, *args, **kwargs):
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1090
        super(TestSuite, self).__init__(*args, **kwargs)
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1091
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1092
        self._runner = runner
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1093
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1094
    def run(self, result):
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1095
        self._runner._executetests(self._tests, result=result)
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1096
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1097
        return result
2e22954b97e3 run-tests: define a custom TestSuite that uses _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21438
diff changeset
  1098
21429
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1099
class TextTestRunner(unittest.TextTestRunner):
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1100
    """Custom unittest test runner that uses appropriate settings."""
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1101
21459
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1102
    def __init__(self, runner, *args, **kwargs):
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1103
        super(TextTestRunner, self).__init__(*args, **kwargs)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1104
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1105
        self._runner = runner
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1106
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1107
    def run(self, test):
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1108
        result = TestResult(self._runner.options, self.stream,
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1109
                            self.descriptions, self.verbosity)
21459
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1110
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1111
        test(result)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1112
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1113
        failed = len(result.failures)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1114
        warned = len(result.warned)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1115
        skipped = len(result.skipped)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1116
        ignored = len(result.ignored)
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1117
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1118
        self.stream.writeln('')
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1119
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1120
        if not self._runner.options.noskips:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1121
            for test, msg in result.skipped:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1122
                self.stream.writeln('Skipped %s: %s' % (test.name, msg))
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1123
        for test, msg in result.warned:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1124
            self.stream.writeln('Warned %s: %s' % (test.name, msg))
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1125
        for test, msg in result.failures:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1126
            self.stream.writeln('Failed %s: %s' % (test.name, msg))
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1127
        for test, msg in result.errors:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1128
            self.stream.writeln('Errored %s: %s' % (test.name, msg))
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1129
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1130
        self._runner._checkhglib('Tested')
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1131
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1132
        # This differs from unittest's default output in that we don't count
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1133
        # skipped and ignored tests as part of the total test count.
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1134
        self.stream.writeln('# Ran %d tests, %d skipped, %d warned, %d failed.'
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1135
            % (result.testsRun - skipped - ignored,
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1136
               skipped + ignored, warned, failed))
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1137
        if failed:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1138
            self.stream.writeln('python hash seed: %s' %
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1139
                os.environ['PYTHONHASHSEED'])
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1140
        if self._runner.options.time:
d5945324b130 run-tests: print compatible output from TextTestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21458
diff changeset
  1141
            self._runner._outputtimes()
21429
203ed3cf6c81 run-tests: define custom result and runner classes for unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21428
diff changeset
  1142
21340
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1143
class TestRunner(object):
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1144
    """Holds context for executing tests.
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1145
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1146
    Tests rely on a lot of state. This object holds it for them.
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1147
    """
21357
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1148
21365
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1149
    REQUIREDTOOLS = [
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1150
        os.path.basename(sys.executable),
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1151
        'diff',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1152
        'grep',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1153
        'unzip',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1154
        'gunzip',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1155
        'bunzip2',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1156
        'sed',
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1157
    ]
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1158
21357
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1159
    TESTTYPES = [
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1160
        ('.py', PythonTest, '.out'),
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1161
        ('.t', TTest, ''),
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1162
    ]
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1163
21341
cb88d4a04f58 run-tests: move TESTDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21340
diff changeset
  1164
    def __init__(self):
21348
b3399154505f run-tests: add options to runner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21347
diff changeset
  1165
        self.options = None
21341
cb88d4a04f58 run-tests: move TESTDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21340
diff changeset
  1166
        self.testdir = None
21342
1ad7aabba14e run-tests: move HGTMP out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21341
diff changeset
  1167
        self.hgtmp = None
21343
93511a595766 run-tests: move INST out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21342
diff changeset
  1168
        self.inst = None
21344
2e1aa8c1ee37 run-tests: move BINDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21343
diff changeset
  1169
        self.bindir = None
21345
8e7b0f4d6ac7 run-tests: move TMPBINDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21344
diff changeset
  1170
        self.tmpbinddir = None
21346
02087bc4f143 run-tests: move PYTHONDIR out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21345
diff changeset
  1171
        self.pythondir = None
21347
5b1b31137f95 run-tests: move COVERAGE_FILE out of a global
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21346
diff changeset
  1172
        self.coveragefile = None
21358
fcc2e02e91a2 run-tests: move times global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21357
diff changeset
  1173
        self.times = [] # Holds execution times of tests.
21359
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1174
        self.results = {
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1175
            '.': [],
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1176
            '!': [],
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1177
            '~': [],
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1178
            's': [],
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1179
            'i': [],
21438
f647287b44d1 run-tests: pass an optional TestResult into _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21437
diff changeset
  1180
            'u': [],
21359
7982475da46a run-tests: move results global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21358
diff changeset
  1181
        }
21361
0fdf92500012 run-tests: move abort global to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21360
diff changeset
  1182
        self.abort = [False]
21352
39fd89fbbc3c run-tests: move createdfiles out of a global and into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21351
diff changeset
  1183
        self._createdfiles = []
21385
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1184
        self._hgpath = None
21340
fda36de1cb0e run-tests: establish a class to hold testing state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21339
diff changeset
  1185
21376
e4366bc08879 run-tests: move option parser logic to TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21375
diff changeset
  1186
    def run(self, args, parser=None):
21366
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1187
        """Run the test suite."""
21375
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1188
        oldmask = os.umask(022)
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1189
        try:
21376
e4366bc08879 run-tests: move option parser logic to TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21375
diff changeset
  1190
            parser = parser or getparser()
e4366bc08879 run-tests: move option parser logic to TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21375
diff changeset
  1191
            options, args = parseargs(args, parser)
e4366bc08879 run-tests: move option parser logic to TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21375
diff changeset
  1192
            self.options = options
e4366bc08879 run-tests: move option parser logic to TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21375
diff changeset
  1193
21375
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1194
            self._checktools()
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1195
            tests = self.findtests(args)
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1196
            return self._run(tests)
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1197
        finally:
bd70dcb91af6 run-tests: move umask into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21374
diff changeset
  1198
            os.umask(oldmask)
21366
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1199
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1200
    def _run(self, tests):
21372
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1201
        if self.options.random:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1202
            random.shuffle(tests)
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1203
        else:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1204
            # keywords for slow tests
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1205
            slow = 'svn gendoc check-code-hg'.split()
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1206
            def sortkey(f):
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1207
                # run largest tests first, as they tend to take the longest
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1208
                try:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1209
                    val = -os.stat(f).st_size
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1210
                except OSError, e:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1211
                    if e.errno != errno.ENOENT:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1212
                        raise
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1213
                    return -1e9 # file does not exist, tell early
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1214
                for kw in slow:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1215
                    if kw in f:
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1216
                        val *= 10
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1217
                return val
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1218
            tests.sort(key=sortkey)
3a44787e50e2 run-tests: move test shuffling and sorting into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21371
diff changeset
  1219
21371
a10ba7870c2d run-tests: assign testdir in TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21370
diff changeset
  1220
        self.testdir = os.environ['TESTDIR'] = os.getcwd()
a10ba7870c2d run-tests: assign testdir in TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21370
diff changeset
  1221
21370
97475f27bebe run-tests: move hash seed logic to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21369
diff changeset
  1222
        if 'PYTHONHASHSEED' not in os.environ:
97475f27bebe run-tests: move hash seed logic to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21369
diff changeset
  1223
            # use a random python hash seed all the time
97475f27bebe run-tests: move hash seed logic to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21369
diff changeset
  1224
            # we do the randomness ourself to know what seed is used
97475f27bebe run-tests: move hash seed logic to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21369
diff changeset
  1225
            os.environ['PYTHONHASHSEED'] = str(random.getrandbits(32))
97475f27bebe run-tests: move hash seed logic to TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21369
diff changeset
  1226
21369
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1227
        if self.options.tmpdir:
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1228
            self.options.keep_tmpdir = True
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1229
            tmpdir = self.options.tmpdir
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1230
            if os.path.exists(tmpdir):
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1231
                # Meaning of tmpdir has changed since 1.3: we used to create
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1232
                # HGTMP inside tmpdir; now HGTMP is tmpdir.  So fail if
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1233
                # tmpdir already exists.
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1234
                print "error: temp dir %r already exists" % tmpdir
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1235
                return 1
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1236
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1237
                # Automatically removing tmpdir sounds convenient, but could
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1238
                # really annoy anyone in the habit of using "--tmpdir=/tmp"
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1239
                # or "--tmpdir=$HOME".
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1240
                #vlog("# Removing temp dir", tmpdir)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1241
                #shutil.rmtree(tmpdir)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1242
            os.makedirs(tmpdir)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1243
        else:
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1244
            d = None
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1245
            if os.name == 'nt':
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1246
                # without this, we get the default temp dir location, but
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1247
                # in all lowercase, which causes troubles with paths (issue3490)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1248
                d = os.getenv('TMP')
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1249
            tmpdir = tempfile.mkdtemp('', 'hgtests.', d)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1250
        self.hgtmp = os.environ['HGTMP'] = os.path.realpath(tmpdir)
1d0aa8bccc87 run-tests: move tmpdir calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21368
diff changeset
  1251
21368
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1252
        if self.options.with_hg:
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1253
            self.inst = None
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1254
            self.bindir = os.path.dirname(os.path.realpath(
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1255
                                          self.options.with_hg))
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1256
            self.tmpbindir = os.path.join(self.hgtmp, 'install', 'bin')
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1257
            os.makedirs(self.tmpbindir)
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1258
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1259
            # This looks redundant with how Python initializes sys.path from
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1260
            # the location of the script being executed.  Needed because the
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1261
            # "hg" specified by --with-hg is not the only Python script
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1262
            # executed in the test suite that needs to import 'mercurial'
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1263
            # ... which means it's not really redundant at all.
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1264
            self.pythondir = self.bindir
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1265
        else:
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1266
            self.inst = os.path.join(self.hgtmp, "install")
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1267
            self.bindir = os.environ["BINDIR"] = os.path.join(self.inst,
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1268
                                                              "bin")
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1269
            self.tmpbindir = self.bindir
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1270
            self.pythondir = os.path.join(self.inst, "lib", "python")
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1271
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1272
        os.environ["BINDIR"] = self.bindir
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1273
        os.environ["PYTHON"] = PYTHON
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1274
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1275
        path = [self.bindir] + os.environ["PATH"].split(os.pathsep)
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1276
        if self.tmpbindir != self.bindir:
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1277
            path = [self.tmpbindir] + path
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1278
        os.environ["PATH"] = os.pathsep.join(path)
a884548f5421 run-tests: move more path calculations into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21367
diff changeset
  1279
21367
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1280
        # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1281
        # can run .../tests/run-tests.py test-foo where test-foo
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1282
        # adds an extension to HGRC. Also include run-test.py directory to
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1283
        # import modules like heredoctest.
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1284
        pypath = [self.pythondir, self.testdir,
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1285
                  os.path.abspath(os.path.dirname(__file__))]
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1286
        # We have to augment PYTHONPATH, rather than simply replacing
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1287
        # it, in case external libraries are only available via current
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1288
        # PYTHONPATH.  (In particular, the Subversion bindings on OS X
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1289
        # are in /opt/subversion.)
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1290
        oldpypath = os.environ.get(IMPL_PATH)
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1291
        if oldpypath:
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1292
            pypath.append(oldpypath)
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1293
        os.environ[IMPL_PATH] = os.pathsep.join(pypath)
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1294
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1295
        self.coveragefile = os.path.join(self.testdir, '.coverage')
522e3d24a461 run-tests: move pypath manipulation into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21366
diff changeset
  1296
21366
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1297
        vlog("# Using TESTDIR", self.testdir)
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1298
        vlog("# Using HGTMP", self.hgtmp)
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1299
        vlog("# Using PATH", os.environ["PATH"])
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1300
        vlog("# Using", IMPL_PATH, os.environ[IMPL_PATH])
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1301
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1302
        try:
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1303
            return self._runtests(tests) or 0
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1304
        finally:
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1305
            time.sleep(.1)
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1306
            self._cleanup()
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1307
21363
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1308
    def findtests(self, args):
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1309
        """Finds possible test files from arguments.
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1310
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1311
        If you wish to inject custom tests into the test harness, this would
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1312
        be a good function to monkeypatch or override in a derived class.
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1313
        """
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1314
        if not args:
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1315
            if self.options.changed:
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1316
                proc = Popen4('hg st --rev "%s" -man0 .' %
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1317
                              self.options.changed, None, 0)
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1318
                stdout, stderr = proc.communicate()
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1319
                args = stdout.strip('\0').split('\0')
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1320
            else:
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1321
                args = os.listdir('.')
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1322
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1323
        return [t for t in args
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1324
                if os.path.basename(t).startswith('test-')
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1325
                    and (t.endswith('.py') or t.endswith('.t'))]
00e5f5b9fc90 run-tests: move test discovery logic into a function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21362
diff changeset
  1326
21366
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1327
    def _runtests(self, tests):
21360
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1328
        try:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1329
            if self.inst:
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1330
                self._installhg()
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1331
                self._checkhglib("Testing")
21360
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1332
            else:
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1333
                self._usecorrectpython()
21360
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1334
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1335
            if self.options.restart:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1336
                orig = list(tests)
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1337
                while tests:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1338
                    if os.path.exists(tests[0] + ".err"):
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1339
                        break
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1340
                    tests.pop(0)
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1341
                if not tests:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1342
                    print "running all tests"
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1343
                    tests = orig
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1344
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1345
            tests = [self._gettest(t, i) for i, t in enumerate(tests)]
21437
d9532be2fc4d run-tests: pass Test instances into TestRunner._executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21436
diff changeset
  1346
21458
c42219733f30 run-tests: don't print results in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21457
diff changeset
  1347
            failed = False
c42219733f30 run-tests: don't print results in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21457
diff changeset
  1348
            warned = False
c42219733f30 run-tests: don't print results in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21457
diff changeset
  1349
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1350
            suite = TestSuite(self, tests=tests)
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1351
            verbosity = 1
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1352
            if self.options.verbose:
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1353
                verbosity = 2
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1354
            runner = TextTestRunner(self, verbosity=verbosity)
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1355
            runner.run(suite)
21360
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1356
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1357
            if self.options.anycoverage:
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1358
                self._outputcoverage()
21360
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1359
        except KeyboardInterrupt:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1360
            failed = True
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1361
            print "\ninterrupted!"
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1362
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1363
        if failed:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1364
            return 1
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1365
        if warned:
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1366
            return 80
becce297ae0c run-tests: move runtests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21359
diff changeset
  1367
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1368
    def _gettest(self, test, count):
21357
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1369
        """Obtain a Test by looking at its filename.
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1370
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1371
        Returns a Test instance. The Test may not be runnable if it doesn't
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1372
        map to a known type.
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1373
        """
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1374
        lctest = test.lower()
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1375
        refpath = os.path.join(self.testdir, test)
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1376
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1377
        testcls = Test
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1378
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1379
        for ext, cls, out in self.TESTTYPES:
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1380
            if lctest.endswith(ext):
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1381
                testcls = cls
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1382
                refpath = os.path.join(self.testdir, test + out)
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1383
                break
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1384
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1385
        t = testcls(self, test, count, refpath)
21426
791bdd65acd3 run-tests: initial support for running tests with unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21388
diff changeset
  1386
791bdd65acd3 run-tests: initial support for running tests with unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21388
diff changeset
  1387
        class MercurialTest(unittest.TestCase):
21427
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1388
            def __init__(self, name, *args, **kwargs):
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1389
                super(MercurialTest, self).__init__(*args, **kwargs)
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1390
                self.name = name
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1391
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1392
            def shortDescription(self):
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1393
                return self.name
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1394
21428
3df2ecf8d545 run-tests: start to report test results against TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21427
diff changeset
  1395
            # Need to stash away the TestResult since we do custom things
3df2ecf8d545 run-tests: start to report test results against TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21427
diff changeset
  1396
            # with it.
3df2ecf8d545 run-tests: start to report test results against TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21427
diff changeset
  1397
            def run(self, result):
21448
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1398
                result.startTest(self)
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
  1399
                try:
21448
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1400
                    try:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1401
                        t.setUp()
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1402
                    except (KeyboardInterrupt, SystemExit):
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1403
                        raise
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1404
                    except Exception:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1405
                        result.addError(self, sys.exc_info())
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1406
                        return
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
  1407
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
  1408
                    success = False
21448
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1409
                    try:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1410
                        self.runTest()
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1411
                    except KeyboardInterrupt:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1412
                        raise
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1413
                    except SkipTest, e:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1414
                        result.addSkip(self, str(e))
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1415
                    except IgnoreTest, e:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1416
                        result.addIgnore(self, str(e))
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1417
                    except WarnTest, e:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1418
                        result.addWarn(self, str(e))
21462
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1419
                    except self.failureException, e:
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1420
                        # This differs from unittest in that we don't capture
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1421
                        # the stack trace. This is for historical reasons and
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1422
                        # this decision could be revisted in the future,
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1423
                        # especially for PythonTest instances.
8a4ef661f08d run-tests: make failure reporting in unittest mode equivalent to default
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21461
diff changeset
  1424
                        result.addFailure(self, str(e))
21448
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1425
                    except Exception:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1426
                        result.addError(self, sys.exc_info())
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1427
                    else:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1428
                        success = True
21446
9a3b4f795f62 run-tests: support setUp() and tearDown() in TestCase wrapper
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21445
diff changeset
  1429
21448
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1430
                    try:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1431
                        t.tearDown()
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1432
                    except (KeyboardInterrupt, SystemExit):
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1433
                        raise
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1434
                    except Exception:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1435
                        result.addError(self, sys.exc_info())
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1436
                        success = False
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1437
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1438
                    if success:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1439
                        result.addSuccess(self)
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1440
                finally:
f2dbbcacc763 run-tests: keep track of test start and stop in MercurialTest.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21447
diff changeset
  1441
                    result.stopTest(self)
21428
3df2ecf8d545 run-tests: start to report test results against TestResult
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21427
diff changeset
  1442
21426
791bdd65acd3 run-tests: initial support for running tests with unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21388
diff changeset
  1443
            def runTest(self):
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1444
                t.run()
21426
791bdd65acd3 run-tests: initial support for running tests with unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21388
diff changeset
  1445
21436
4528e95345d7 run-tests: define cleanup() on unittest class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21435
diff changeset
  1446
            # We need this proxy until tearDown() is implemented.
4528e95345d7 run-tests: define cleanup() on unittest class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21435
diff changeset
  1447
            def cleanup(self):
4528e95345d7 run-tests: define cleanup() on unittest class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21435
diff changeset
  1448
                return t.cleanup()
4528e95345d7 run-tests: define cleanup() on unittest class
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21435
diff changeset
  1449
21427
60f944758ad4 run-tests: give unittest wrapper a short description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21426
diff changeset
  1450
        return MercurialTest(test)
21357
4c4f64b8df3c run-tests: move gettest() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21356
diff changeset
  1451
21366
5047248536c5 run-tests: establish TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21365
diff changeset
  1452
    def _cleanup(self):
21350
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1453
        """Clean up state from this test invocation."""
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1454
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1455
        if self.options.keep_tmpdir:
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1456
            return
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1457
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1458
        vlog("# Cleaning up HGTMP", self.hgtmp)
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1459
        shutil.rmtree(self.hgtmp, True)
21352
39fd89fbbc3c run-tests: move createdfiles out of a global and into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21351
diff changeset
  1460
        for f in self._createdfiles:
21350
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1461
            try:
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1462
                os.remove(f)
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1463
            except OSError:
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1464
                pass
dfcef61f5bd4 run-tests: move cleanup() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21349
diff changeset
  1465
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1466
    def _usecorrectpython(self):
21351
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1467
        # Some tests run the Python interpreter. They must use the
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1468
        # same interpreter or bad things will happen.
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1469
        pyexename = sys.platform == 'win32' and 'python.exe' or 'python'
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1470
        if getattr(os, 'symlink', None):
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1471
            vlog("# Making python executable in test path a symlink to '%s'" %
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1472
                 sys.executable)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1473
            mypython = os.path.join(self.tmpbindir, pyexename)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1474
            try:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1475
                if os.readlink(mypython) == sys.executable:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1476
                    return
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1477
                os.unlink(mypython)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1478
            except OSError, err:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1479
                if err.errno != errno.ENOENT:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1480
                    raise
21365
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1481
            if self._findprogram(pyexename) != sys.executable:
21351
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1482
                try:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1483
                    os.symlink(sys.executable, mypython)
21352
39fd89fbbc3c run-tests: move createdfiles out of a global and into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21351
diff changeset
  1484
                    self._createdfiles.append(mypython)
21351
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1485
                except OSError, err:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1486
                    # child processes may race, which is harmless
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1487
                    if err.errno != errno.EEXIST:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1488
                        raise
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1489
        else:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1490
            exedir, exename = os.path.split(sys.executable)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1491
            vlog("# Modifying search path to find %s as %s in '%s'" %
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1492
                 (exename, pyexename, exedir))
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1493
            path = os.environ['PATH'].split(os.pathsep)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1494
            while exedir in path:
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1495
                path.remove(exedir)
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1496
            os.environ['PATH'] = os.pathsep.join([exedir] + path)
21365
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1497
            if not self._findprogram(pyexename):
21351
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1498
                print "WARNING: Cannot find %s in search path" % pyexename
fe5647506565 run-tests: move usecorrectpython() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21350
diff changeset
  1499
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1500
    def _installhg(self):
21353
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1501
        vlog("# Performing temporary installation of HG")
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1502
        installerrs = os.path.join("tests", "install.err")
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1503
        compiler = ''
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1504
        if self.options.compiler:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1505
            compiler = '--compiler ' + self.options.compiler
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1506
        pure = self.options.pure and "--pure" or ""
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1507
        py3 = ''
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1508
        if sys.version_info[0] == 3:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1509
            py3 = '--c2to3'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1510
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1511
        # Run installer in hg root
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1512
        script = os.path.realpath(sys.argv[0])
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1513
        hgroot = os.path.dirname(os.path.dirname(script))
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1514
        os.chdir(hgroot)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1515
        nohome = '--home=""'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1516
        if os.name == 'nt':
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1517
            # The --home="" trick works only on OS where os.sep == '/'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1518
            # because of a distutils convert_path() fast-path. Avoid it at
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1519
            # least on Windows for now, deal with .pydistutils.cfg bugs
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1520
            # when they happen.
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1521
            nohome = ''
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1522
        cmd = ('%(exe)s setup.py %(py3)s %(pure)s clean --all'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1523
               ' build %(compiler)s --build-base="%(base)s"'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1524
               ' install --force --prefix="%(prefix)s"'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1525
               ' --install-lib="%(libdir)s"'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1526
               ' --install-scripts="%(bindir)s" %(nohome)s >%(logfile)s 2>&1'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1527
               % {'exe': sys.executable, 'py3': py3, 'pure': pure,
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1528
                  'compiler': compiler,
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1529
                  'base': os.path.join(self.hgtmp, "build"),
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1530
                  'prefix': self.inst, 'libdir': self.pythondir,
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1531
                  'bindir': self.bindir,
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1532
                  'nohome': nohome, 'logfile': installerrs})
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1533
        vlog("# Running", cmd)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1534
        if os.system(cmd) == 0:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1535
            if not self.options.verbose:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1536
                os.remove(installerrs)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1537
        else:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1538
            f = open(installerrs)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1539
            for line in f:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1540
                print line,
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1541
            f.close()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1542
            sys.exit(1)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1543
        os.chdir(self.testdir)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1544
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1545
        self._usecorrectpython()
21353
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1546
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1547
        if self.options.py3k_warnings and not self.options.anycoverage:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1548
            vlog("# Updating hg command to enable Py3k Warnings switch")
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1549
            f = open(os.path.join(self.bindir, 'hg'), 'r')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1550
            lines = [line.rstrip() for line in f]
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1551
            lines[0] += ' -3'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1552
            f.close()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1553
            f = open(os.path.join(self.bindir, 'hg'), 'w')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1554
            for line in lines:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1555
                f.write(line + '\n')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1556
            f.close()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1557
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1558
        hgbat = os.path.join(self.bindir, 'hg.bat')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1559
        if os.path.isfile(hgbat):
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1560
            # hg.bat expects to be put in bin/scripts while run-tests.py
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1561
            # installation layout put it in bin/ directly. Fix it
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1562
            f = open(hgbat, 'rb')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1563
            data = f.read()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1564
            f.close()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1565
            if '"%~dp0..\python" "%~dp0hg" %*' in data:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1566
                data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1567
                                    '"%~dp0python" "%~dp0hg" %*')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1568
                f = open(hgbat, 'wb')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1569
                f.write(data)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1570
                f.close()
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1571
            else:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1572
                print 'WARNING: cannot fix hg.bat reference to python.exe'
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1573
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1574
        if self.options.anycoverage:
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1575
            custom = os.path.join(self.testdir, 'sitecustomize.py')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1576
            target = os.path.join(self.pythondir, 'sitecustomize.py')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1577
            vlog('# Installing coverage trigger to %s' % target)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1578
            shutil.copyfile(custom, target)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1579
            rc = os.path.join(self.testdir, '.coveragerc')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1580
            vlog('# Installing coverage rc to %s' % rc)
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1581
            os.environ['COVERAGE_PROCESS_START'] = rc
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1582
            fn = os.path.join(self.inst, '..', '.coverage')
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1583
            os.environ['COVERAGE_FILE'] = fn
a42a5195a182 run-tests: move installhg() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21352
diff changeset
  1584
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1585
    def _checkhglib(self, verb):
21354
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1586
        """Ensure that the 'mercurial' package imported by python is
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1587
        the one we expect it to be.  If not, print a warning to stderr."""
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1588
        expecthg = os.path.join(self.pythondir, 'mercurial')
21385
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1589
        actualhg = self._gethgpath()
21354
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1590
        if os.path.abspath(actualhg) != os.path.abspath(expecthg):
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1591
            sys.stderr.write('warning: %s with unexpected mercurial lib: %s\n'
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1592
                             '         (expected %s)\n'
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1593
                             % (verb, actualhg, expecthg))
21385
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1594
    def _gethgpath(self):
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1595
        """Return the path to the mercurial package that is actually found by
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1596
        the current Python interpreter."""
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1597
        if self._hgpath is not None:
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1598
            return self._hgpath
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1599
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1600
        cmd = '%s -c "import mercurial; print (mercurial.__path__[0])"'
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1601
        pipe = os.popen(cmd % PYTHON)
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1602
        try:
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1603
            self._hgpath = pipe.read().strip()
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1604
        finally:
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1605
            pipe.close()
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1606
28414e5ac9ec run-tests: move _gethgpath() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21384
diff changeset
  1607
        return self._hgpath
21354
29629ef43d39 run-tests: move checkhglib into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21353
diff changeset
  1608
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1609
    def _outputtimes(self):
21355
d83f4e94512a run-tests: move outputtimes() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21354
diff changeset
  1610
        vlog('# Producing time report')
21358
fcc2e02e91a2 run-tests: move times global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21357
diff changeset
  1611
        self.times.sort(key=lambda t: (t[1], t[0]), reverse=True)
21355
d83f4e94512a run-tests: move outputtimes() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21354
diff changeset
  1612
        cols = '%7.3f   %s'
d83f4e94512a run-tests: move outputtimes() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21354
diff changeset
  1613
        print '\n%-7s   %s' % ('Time', 'Test')
21358
fcc2e02e91a2 run-tests: move times global into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21357
diff changeset
  1614
        for test, timetaken in self.times:
21355
d83f4e94512a run-tests: move outputtimes() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21354
diff changeset
  1615
            print cols % (timetaken, test)
d83f4e94512a run-tests: move outputtimes() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21354
diff changeset
  1616
21378
f7ac3c63d844 run-tests: make some methods of TestRunner internal
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21377
diff changeset
  1617
    def _outputcoverage(self):
21356
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1618
        vlog('# Producing coverage report')
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1619
        os.chdir(self.pythondir)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1620
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1621
        def covrun(*args):
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1622
            cmd = 'coverage %s' % ' '.join(args)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1623
            vlog('# Running: %s' % cmd)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1624
            os.system(cmd)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1625
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1626
        covrun('-c')
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1627
        omit = ','.join(os.path.join(x, '*') for x in
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1628
                        [self.bindir, self.testdir])
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1629
        covrun('-i', '-r', '"--omit=%s"' % omit) # report
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1630
        if self.options.htmlcov:
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1631
            htmldir = os.path.join(self.testdir, 'htmlcov')
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1632
            covrun('-i', '-b', '"--directory=%s"' % htmldir,
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1633
                   '"--omit=%s"' % omit)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1634
        if self.options.annotate:
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1635
            adir = os.path.join(self.testdir, 'annotated')
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1636
            if not os.path.isdir(adir):
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1637
                os.mkdir(adir)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1638
            covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
f96d7dfd8cb5 run-tests: move outputcoverage() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21355
diff changeset
  1639
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1640
    def _executetests(self, tests, result):
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1641
        # We modify the list, so copy so callers aren't confused.
21438
f647287b44d1 run-tests: pass an optional TestResult into _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21437
diff changeset
  1642
        tests = list(tests)
f647287b44d1 run-tests: pass an optional TestResult into _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21437
diff changeset
  1643
21362
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1644
        jobs = self.options.jobs
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1645
        done = queue.Queue()
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1646
        running = 0
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1647
21438
f647287b44d1 run-tests: pass an optional TestResult into _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21437
diff changeset
  1648
        def job(test, result):
21362
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1649
            try:
21464
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1650
                test(result)
d19164a018a1 run-tests: execute tests via unittest
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21463
diff changeset
  1651
                done.put(('u', None, None))
21362
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1652
            except KeyboardInterrupt:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1653
                pass
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1654
            except: # re-raises
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1655
                done.put(('!', test, 'run-test raised an error, see traceback'))
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1656
                raise
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1657
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1658
        try:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1659
            while tests or running:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1660
                if not done.empty() or running == jobs or not tests:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1661
                    try:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1662
                        code, test, msg = done.get(True, 1)
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1663
                        self.results[code].append((test, msg))
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1664
                        if self.options.first and code not in '.si':
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1665
                            break
21460
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1666
                        if result and result.shouldStop:
df580990507e run-tests: abort tests after first failure in unittest mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21459
diff changeset
  1667
                            break
21362
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1668
                    except queue.Empty:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1669
                        continue
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1670
                    running -= 1
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1671
                if tests and not running == jobs:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1672
                    test = tests.pop(0)
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1673
                    if self.options.loop:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1674
                        tests.append(test)
21437
d9532be2fc4d run-tests: pass Test instances into TestRunner._executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21436
diff changeset
  1675
                    t = threading.Thread(target=job, name=test.name,
21438
f647287b44d1 run-tests: pass an optional TestResult into _executetests()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21437
diff changeset
  1676
                                         args=(test, result))
21362
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1677
                    t.start()
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1678
                    running += 1
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1679
        except KeyboardInterrupt:
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1680
            self.abort[0] = True
ff4ce72cc8d6 run-tests: move scheduletests() into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21361
diff changeset
  1681
21365
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1682
    def _findprogram(self, program):
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1683
        """Search PATH for a executable program"""
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1684
        for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1685
            name = os.path.join(p, program)
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1686
            if os.name == 'nt' or os.access(name, os.X_OK):
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1687
                return name
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1688
        return None
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1689
21374
592b3d2616d7 run-tests: move checktools into TestRunner.run()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21373
diff changeset
  1690
    def _checktools(self):
21365
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1691
        # Before we go any further, check for pre-requisite tools
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1692
        # stuff from coreutils (cat, rm, etc) are not tested
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1693
        for p in self.REQUIREDTOOLS:
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1694
            if os.name == 'nt' and not p.endswith('.exe'):
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1695
                p += '.exe'
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1696
            found = self._findprogram(p)
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1697
            if found:
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1698
                vlog("# Found prerequisite", p, "at", found)
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1699
            else:
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1700
                print "WARNING: Did not find prerequisite tool: %s " % p
10cf9054d941 run-tests: move program searching into TestRunner
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21364
diff changeset
  1701
13347
ce07defe7d9f run-tests: loadable as module
Simon Heimberg <simohe@besonet.ch>
parents: 13031
diff changeset
  1702
if __name__ == '__main__':
21377
71081f7f9e52 run-tests: eliminate main()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21376
diff changeset
  1703
    runner = TestRunner()
71081f7f9e52 run-tests: eliminate main()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21376
diff changeset
  1704
    sys.exit(runner.run(sys.argv[1:]))