annotate tests/run-tests.py @ 905:b177fde040dd

exchange: use fixed order for obstore content The obsstore content seems unstable from one version of python to another (we most certainly use some dict) we fix the order once and for all.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 22 Apr 2014 17:00:24 -0700
parents 6ee7add34f8b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1 #!/usr/bin/env python
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
2 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
3 # run-tests.py - Run a set of tests on Mercurial
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
4 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
5 # Copyright 2006 Matt Mackall <mpm@selenic.com>
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
6 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
7 # This software may be used and distributed according to the terms of the
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
8 # GNU General Public License version 2 or any later version.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
9
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
10 # Modifying this script is tricky because it has many modes:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
11 # - serial (default) vs parallel (-jN, N > 1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
12 # - no coverage (default) vs coverage (-c, -C, -s)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
13 # - temp install (default) vs specific hg script (--with-hg, --local)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
14 # - tests are a mix of shell scripts and Python scripts
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
15 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
16 # If you change this script, it is recommended that you ensure you
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
17 # haven't broken it by running it in various modes with a representative
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
18 # sample of test scripts. For example:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
19 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
20 # 1) serial, no coverage, temp install:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
21 # ./run-tests.py test-s*
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
22 # 2) serial, no coverage, local hg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
23 # ./run-tests.py --local test-s*
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
24 # 3) serial, coverage, temp install:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
25 # ./run-tests.py -c test-s*
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
26 # 4) serial, coverage, local hg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
27 # ./run-tests.py -c --local test-s* # unsupported
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
28 # 5) parallel, no coverage, temp install:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
29 # ./run-tests.py -j2 test-s*
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
30 # 6) parallel, no coverage, local hg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
31 # ./run-tests.py -j2 --local test-s*
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
32 # 7) parallel, coverage, temp install:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
33 # ./run-tests.py -j2 -c test-s* # currently broken
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
34 # 8) parallel, coverage, local install:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
35 # ./run-tests.py -j2 -c --local test-s* # unsupported (and broken)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
36 # 9) parallel, custom tmp dir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
37 # ./run-tests.py -j2 --tmpdir /tmp/myhgtests
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
38 #
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
39 # (You could use any subset of the tests: test-s* happens to match
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
40 # enough that it's worth doing parallel runs, few enough that it
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
41 # completes fairly quickly, includes both shell and Python scripts, and
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
42 # includes some scripts that run daemon processes.)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
43
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
44 from distutils import version
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
45 import difflib
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
46 import errno
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
47 import optparse
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
48 import os
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
49 import shutil
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
50 import subprocess
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
51 import signal
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
52 import sys
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
53 import tempfile
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
54 import time
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
55 import re
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
56
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
57 closefds = os.name == 'posix'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
58 def Popen4(cmd, bufsize=-1):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
59 p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
60 close_fds=closefds,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
61 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
62 stderr=subprocess.STDOUT)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
63 p.fromchild = p.stdout
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
64 p.tochild = p.stdin
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
65 p.childerr = p.stderr
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
66 return p
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
67
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
68 # reserved exit code to skip test (used by hghave)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
69 SKIPPED_STATUS = 80
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
70 SKIPPED_PREFIX = 'skipped: '
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
71 FAILED_PREFIX = 'hghave check failed: '
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
72 PYTHON = sys.executable
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
73 IMPL_PATH = 'PYTHONPATH'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
74 if 'java' in sys.platform:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
75 IMPL_PATH = 'JYTHONPATH'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
76
530
6ee7add34f8b tests: remove unused required tools
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 21
diff changeset
77 requiredtools = ["python", "diff", "grep", "sed"]
0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
78
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
79 defaults = {
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
80 'jobs': ('HGTEST_JOBS', 1),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
81 'timeout': ('HGTEST_TIMEOUT', 180),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
82 'port': ('HGTEST_PORT', 20059),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
83 }
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
84
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
85 def parseargs():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
86 parser = optparse.OptionParser("%prog [options] [tests]")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
87
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
88 # keep these sorted
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
89 parser.add_option("--blacklist", action="append",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
90 help="skip tests listed in the specified blacklist file")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
91 parser.add_option("-C", "--annotate", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
92 help="output files annotated with coverage")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
93 parser.add_option("--child", type="int",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
94 help="run as child process, summary to given fd")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
95 parser.add_option("-c", "--cover", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
96 help="print a test coverage report")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
97 parser.add_option("-d", "--debug", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
98 help="debug mode: write output of test scripts to console"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
99 " rather than capturing and diff'ing it (disables timeout)")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
100 parser.add_option("-f", "--first", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
101 help="exit on the first test failure")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
102 parser.add_option("--inotify", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
103 help="enable inotify extension when running tests")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
104 parser.add_option("-i", "--interactive", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
105 help="prompt to accept changed output")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
106 parser.add_option("-j", "--jobs", type="int",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
107 help="number of jobs to run in parallel"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
108 " (default: $%s or %d)" % defaults['jobs'])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
109 parser.add_option("--keep-tmpdir", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
110 help="keep temporary directory after running tests")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
111 parser.add_option("-k", "--keywords",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
112 help="run tests matching keywords")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
113 parser.add_option("-l", "--local", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
114 help="shortcut for --with-hg=<testdir>/../hg")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
115 parser.add_option("-n", "--nodiff", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
116 help="skip showing test changes")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
117 parser.add_option("-p", "--port", type="int",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
118 help="port on which servers should listen"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
119 " (default: $%s or %d)" % defaults['port'])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
120 parser.add_option("--pure", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
121 help="use pure Python code instead of C extensions")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
122 parser.add_option("-R", "--restart", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
123 help="restart at last error")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
124 parser.add_option("-r", "--retest", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
125 help="retest failed tests")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
126 parser.add_option("-S", "--noskips", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
127 help="don't report skip tests verbosely")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
128 parser.add_option("-t", "--timeout", type="int",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
129 help="kill errant tests after TIMEOUT seconds"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
130 " (default: $%s or %d)" % defaults['timeout'])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
131 parser.add_option("--tmpdir", type="string",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
132 help="run tests in the given temporary directory"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
133 " (implies --keep-tmpdir)")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
134 parser.add_option("-v", "--verbose", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
135 help="output verbose messages")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
136 parser.add_option("--view", type="string",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
137 help="external diff viewer")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
138 parser.add_option("--with-hg", type="string",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
139 metavar="HG",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
140 help="test using specified hg script rather than a "
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
141 "temporary installation")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
142 parser.add_option("-3", "--py3k-warnings", action="store_true",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
143 help="enable Py3k warnings on Python 2.6+")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
144
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
145 for option, default in defaults.items():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
146 defaults[option] = int(os.environ.get(*default))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
147 parser.set_defaults(**defaults)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
148 (options, args) = parser.parse_args()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
149
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
150 # jython is always pure
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
151 if 'java' in sys.platform or '__pypy__' in sys.modules:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
152 options.pure = True
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
153
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
154 if options.with_hg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
155 if not (os.path.isfile(options.with_hg) and
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
156 os.access(options.with_hg, os.X_OK)):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
157 parser.error('--with-hg must specify an executable hg script')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
158 if not os.path.basename(options.with_hg) == 'hg':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
159 sys.stderr.write('warning: --with-hg should specify an hg script')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
160 if options.local:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
161 testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
162 hgbin = os.path.join(os.path.dirname(testdir), 'hg')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
163 if not os.access(hgbin, os.X_OK):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
164 parser.error('--local specified, but %r not found or not executable'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
165 % hgbin)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
166 options.with_hg = hgbin
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
167
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
168 options.anycoverage = options.cover or options.annotate
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
169 if options.anycoverage:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
170 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
171 import coverage
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
172 covver = version.StrictVersion(coverage.__version__).version
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
173 if covver < (3, 3):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
174 parser.error('coverage options require coverage 3.3 or later')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
175 except ImportError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
176 parser.error('coverage options now require the coverage package')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
177
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
178 if options.anycoverage and options.local:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
179 # this needs some path mangling somewhere, I guess
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
180 parser.error("sorry, coverage options do not work when --local "
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
181 "is specified")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
182
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
183 global vlog
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
184 if options.verbose:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
185 if options.jobs > 1 or options.child is not None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
186 pid = "[%d]" % os.getpid()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
187 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
188 pid = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
189 def vlog(*msg):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
190 if pid:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
191 print pid,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
192 for m in msg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
193 print m,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
194 print
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
195 sys.stdout.flush()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
196 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
197 vlog = lambda *msg: None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
198
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
199 if options.tmpdir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
200 options.tmpdir = os.path.expanduser(options.tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
201
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
202 if options.jobs < 1:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
203 parser.error('--jobs must be positive')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
204 if options.interactive and options.jobs > 1:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
205 print '(--interactive overrides --jobs)'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
206 options.jobs = 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
207 if options.interactive and options.debug:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
208 parser.error("-i/--interactive and -d/--debug are incompatible")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
209 if options.debug:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
210 if options.timeout != defaults['timeout']:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
211 sys.stderr.write(
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
212 'warning: --timeout option ignored with --debug\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
213 options.timeout = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
214 if options.py3k_warnings:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
215 if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
216 parser.error('--py3k-warnings can only be used on Python 2.6+')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
217 if options.blacklist:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
218 blacklist = dict()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
219 for filename in options.blacklist:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
220 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
221 path = os.path.expanduser(os.path.expandvars(filename))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
222 f = open(path, "r")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
223 except IOError, err:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
224 if err.errno != errno.ENOENT:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
225 raise
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
226 print "warning: no such blacklist file: %s" % filename
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
227 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
228
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
229 for line in f.readlines():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
230 line = line.strip()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
231 if line and not line.startswith('#'):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
232 blacklist[line] = filename
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
233
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
234 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
235
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
236 options.blacklist = blacklist
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
237
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
238 return (options, args)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
239
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
240 def rename(src, dst):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
241 """Like os.rename(), trade atomicity and opened files friendliness
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
242 for existing destination support.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
243 """
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
244 shutil.copy(src, dst)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
245 os.remove(src)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
246
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
247 def splitnewlines(text):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
248 '''like str.splitlines, but only split on newlines.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
249 keep line endings.'''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
250 i = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
251 lines = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
252 while True:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
253 n = text.find('\n', i)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
254 if n == -1:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
255 last = text[i:]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
256 if last:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
257 lines.append(last)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
258 return lines
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
259 lines.append(text[i:n + 1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
260 i = n + 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
261
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
262 def parsehghaveoutput(lines):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
263 '''Parse hghave log lines.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
264 Return tuple of lists (missing, failed):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
265 * the missing/unknown features
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
266 * the features for which existence check failed'''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
267 missing = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
268 failed = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
269 for line in lines:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
270 if line.startswith(SKIPPED_PREFIX):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
271 line = line.splitlines()[0]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
272 missing.append(line[len(SKIPPED_PREFIX):])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
273 elif line.startswith(FAILED_PREFIX):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
274 line = line.splitlines()[0]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
275 failed.append(line[len(FAILED_PREFIX):])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
276
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
277 return missing, failed
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
278
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
279 def showdiff(expected, output, ref, err):
21
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
280 try:
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
281 for line in difflib.unified_diff(expected, output, ref, err):
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
282 sys.stdout.write(line)
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
283 except IOError, ex:
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
284 print >>sys.stderr, 'BORKEN PIPE', ex.errno
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
285 pass
0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
286
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
287 def findprogram(program):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
288 """Search PATH for a executable program"""
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
289 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
290 name = os.path.join(p, program)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
291 if os.access(name, os.X_OK):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
292 return name
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
293 return None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
294
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
295 def checktools():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
296 # Before we go any further, check for pre-requisite tools
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
297 # stuff from coreutils (cat, rm, etc) are not tested
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
298 for p in requiredtools:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
299 if os.name == 'nt':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
300 p += '.exe'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
301 found = findprogram(p)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
302 if found:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
303 vlog("# Found prerequisite", p, "at", found)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
304 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
305 print "WARNING: Did not find prerequisite tool: "+p
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
306
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
307 def killdaemons():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
308 # Kill off any leftover daemon processes
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
309 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
310 fp = open(DAEMON_PIDS)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
311 for line in fp:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
312 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
313 pid = int(line)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
314 except ValueError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
315 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
316 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
317 os.kill(pid, 0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
318 vlog('# Killing daemon process %d' % pid)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
319 os.kill(pid, signal.SIGTERM)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
320 time.sleep(0.25)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
321 os.kill(pid, 0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
322 vlog('# Daemon process %d is stuck - really killing it' % pid)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
323 os.kill(pid, signal.SIGKILL)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
324 except OSError, err:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
325 if err.errno != errno.ESRCH:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
326 raise
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
327 fp.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
328 os.unlink(DAEMON_PIDS)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
329 except IOError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
330 pass
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
331
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
332 def cleanup(options):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
333 if not options.keep_tmpdir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
334 vlog("# Cleaning up HGTMP", HGTMP)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
335 shutil.rmtree(HGTMP, True)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
336
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
337 def usecorrectpython():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
338 # some tests run python interpreter. they must use same
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
339 # interpreter we use or bad things will happen.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
340 exedir, exename = os.path.split(sys.executable)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
341 if exename == 'python':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
342 path = findprogram('python')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
343 if os.path.dirname(path) == exedir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
344 return
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
345 vlog('# Making python executable in test path use correct Python')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
346 mypython = os.path.join(BINDIR, 'python')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
347 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
348 os.symlink(sys.executable, mypython)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
349 except AttributeError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
350 # windows fallback
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
351 shutil.copyfile(sys.executable, mypython)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
352 shutil.copymode(sys.executable, mypython)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
353
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
354 def installhg(options):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
355 vlog("# Performing temporary installation of HG")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
356 installerrs = os.path.join("tests", "install.err")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
357 pure = options.pure and "--pure" or ""
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
358
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
359 # Run installer in hg root
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
360 script = os.path.realpath(sys.argv[0])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
361 hgroot = os.path.dirname(os.path.dirname(script))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
362 os.chdir(hgroot)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
363 nohome = '--home=""'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
364 if os.name == 'nt':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
365 # The --home="" trick works only on OS where os.sep == '/'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
366 # because of a distutils convert_path() fast-path. Avoid it at
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
367 # least on Windows for now, deal with .pydistutils.cfg bugs
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
368 # when they happen.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
369 nohome = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
370 cmd = ('%s setup.py %s clean --all'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
371 ' build --build-base="%s"'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
372 ' install --force --prefix="%s" --install-lib="%s"'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
373 ' --install-scripts="%s" %s >%s 2>&1'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
374 % (sys.executable, pure, os.path.join(HGTMP, "build"),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
375 INST, PYTHONDIR, BINDIR, nohome, installerrs))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
376 vlog("# Running", cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
377 if os.system(cmd) == 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
378 if not options.verbose:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
379 os.remove(installerrs)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
380 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
381 f = open(installerrs)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
382 for line in f:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
383 print line,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
384 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
385 sys.exit(1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
386 os.chdir(TESTDIR)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
387
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
388 usecorrectpython()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
389
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
390 vlog("# Installing dummy diffstat")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
391 f = open(os.path.join(BINDIR, 'diffstat'), 'w')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
392 f.write('#!' + sys.executable + '\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
393 'import sys\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
394 'files = 0\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
395 'for line in sys.stdin:\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
396 ' if line.startswith("diff "):\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
397 ' files += 1\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
398 'sys.stdout.write("files patched: %d\\n" % files)\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
399 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
400 os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
401
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
402 if options.py3k_warnings and not options.anycoverage:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
403 vlog("# Updating hg command to enable Py3k Warnings switch")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
404 f = open(os.path.join(BINDIR, 'hg'), 'r')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
405 lines = [line.rstrip() for line in f]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
406 lines[0] += ' -3'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
407 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
408 f = open(os.path.join(BINDIR, 'hg'), 'w')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
409 for line in lines:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
410 f.write(line + '\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
411 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
412
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
413 if options.anycoverage:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
414 custom = os.path.join(TESTDIR, 'sitecustomize.py')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
415 target = os.path.join(PYTHONDIR, 'sitecustomize.py')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
416 vlog('# Installing coverage trigger to %s' % target)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
417 shutil.copyfile(custom, target)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
418 rc = os.path.join(TESTDIR, '.coveragerc')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
419 vlog('# Installing coverage rc to %s' % rc)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
420 os.environ['COVERAGE_PROCESS_START'] = rc
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
421 fn = os.path.join(INST, '..', '.coverage')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
422 os.environ['COVERAGE_FILE'] = fn
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
423
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
424 def outputcoverage(options):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
425
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
426 vlog('# Producing coverage report')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
427 os.chdir(PYTHONDIR)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
428
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
429 def covrun(*args):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
430 cmd = 'coverage %s' % ' '.join(args)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
431 vlog('# Running: %s' % cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
432 os.system(cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
433
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
434 if options.child:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
435 return
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
436
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
437 covrun('-c')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
438 omit = ','.join([BINDIR, TESTDIR])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
439 covrun('-i', '-r', '"--omit=%s"' % omit) # report
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
440 if options.annotate:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
441 adir = os.path.join(TESTDIR, 'annotated')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
442 if not os.path.isdir(adir):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
443 os.mkdir(adir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
444 covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
445
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
446 class Timeout(Exception):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
447 pass
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
448
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
449 def alarmed(signum, frame):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
450 raise Timeout
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
451
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
452 def pytest(test, options, replacements):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
453 py3kswitch = options.py3k_warnings and ' -3' or ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
454 cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
455 vlog("# Running", cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
456 return run(cmd, options, replacements)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
457
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
458 def shtest(test, options, replacements):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
459 cmd = '"%s"' % test
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
460 vlog("# Running", cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
461 return run(cmd, options, replacements)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
462
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
463 needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
464 escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
465 escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
466 escapemap.update({'\\': '\\\\', '\r': r'\r'})
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
467 def escapef(m):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
468 return escapemap[m.group(0)]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
469 def stringescape(s):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
470 return escapesub(escapef, s)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
471
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
472 def tsttest(test, options, replacements):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
473 t = open(test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
474 out = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
475 script = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
476 salt = "SALT" + str(time.time())
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
477
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
478 pos = prepos = -1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
479 after = {}
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
480 expected = {}
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
481 for n, l in enumerate(t):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
482 if not l.endswith('\n'):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
483 l += '\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
484 if l.startswith(' $ '): # commands
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
485 after.setdefault(pos, []).append(l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
486 prepos = pos
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
487 pos = n
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
488 script.append('echo %s %s $?\n' % (salt, n))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
489 script.append(l[4:])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
490 elif l.startswith(' > '): # continuations
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
491 after.setdefault(prepos, []).append(l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
492 script.append(l[4:])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
493 elif l.startswith(' '): # results
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
494 # queue up a list of expected results
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
495 expected.setdefault(pos, []).append(l[2:])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
496 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
497 # non-command/result - queue up for merged output
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
498 after.setdefault(pos, []).append(l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
499
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
500 t.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
501
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
502 script.append('echo %s %s $?\n' % (salt, n + 1))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
503
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
504 fd, name = tempfile.mkstemp(suffix='hg-tst')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
505
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
506 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
507 for l in script:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
508 os.write(fd, l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
509 os.close(fd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
510
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
511 cmd = '/bin/sh "%s"' % name
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
512 vlog("# Running", cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
513 exitcode, output = run(cmd, options, replacements)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
514 # do not merge output if skipped, return hghave message instead
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
515 # similarly, with --debug, output is None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
516 if exitcode == SKIPPED_STATUS or output is None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
517 return exitcode, output
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
518 finally:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
519 os.remove(name)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
520
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
521 def rematch(el, l):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
522 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
523 # ensure that the regex matches to the end of the string
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
524 return re.match(el + r'\Z', l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
525 except re.error:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
526 # el is an invalid regex
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
527 return False
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
528
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
529 def globmatch(el, l):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
530 # The only supported special characters are * and ?. Escaping is
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
531 # supported.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
532 i, n = 0, len(el)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
533 res = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
534 while i < n:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
535 c = el[i]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
536 i += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
537 if c == '\\' and el[i] in '*?\\':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
538 res += el[i - 1:i + 1]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
539 i += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
540 elif c == '*':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
541 res += '.*'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
542 elif c == '?':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
543 res += '.'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
544 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
545 res += re.escape(c)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
546 return rematch(res, l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
547
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
548 pos = -1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
549 postout = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
550 ret = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
551 for n, l in enumerate(output):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
552 lout, lcmd = l, None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
553 if salt in l:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
554 lout, lcmd = l.split(salt, 1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
555
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
556 if lout:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
557 if lcmd:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
558 lout += ' (no-eol)\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
559
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
560 el = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
561 if pos in expected and expected[pos]:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
562 el = expected[pos].pop(0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
563
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
564 if el == lout: # perfect match (fast)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
565 postout.append(" " + lout)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
566 elif (el and
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
567 (el.endswith(" (re)\n") and rematch(el[:-6] + '\n', lout) or
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
568 el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', lout)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
569 or el.endswith(" (esc)\n") and
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
570 el.decode('string-escape') == l)):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
571 postout.append(" " + el) # fallback regex/glob/esc match
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
572 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
573 if needescape(lout):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
574 lout = stringescape(lout.rstrip('\n')) + " (esc)\n"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
575 postout.append(" " + lout) # let diff deal with it
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
576
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
577 if lcmd:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
578 # add on last return code
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
579 ret = int(lcmd.split()[1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
580 if ret != 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
581 postout.append(" [%s]\n" % ret)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
582 if pos in after:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
583 postout += after.pop(pos)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
584 pos = int(lcmd.split()[0])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
585
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
586 if pos in after:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
587 postout += after.pop(pos)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
588
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
589 return exitcode, postout
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
590
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
591 wifexited = getattr(os, "WIFEXITED", lambda x: False)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
592 def run(cmd, options, replacements):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
593 """Run command in a sub-process, capturing the output (stdout and stderr).
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
594 Return a tuple (exitcode, output). output is None in debug mode."""
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
595 # TODO: Use subprocess.Popen if we're running on Python 2.4
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
596 if options.debug:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
597 proc = subprocess.Popen(cmd, shell=True)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
598 ret = proc.wait()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
599 return (ret, None)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
600
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
601 if os.name == 'nt' or sys.platform.startswith('java'):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
602 tochild, fromchild = os.popen4(cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
603 tochild.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
604 output = fromchild.read()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
605 ret = fromchild.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
606 if ret is None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
607 ret = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
608 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
609 proc = Popen4(cmd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
610 def cleanup():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
611 os.kill(proc.pid, signal.SIGTERM)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
612 ret = proc.wait()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
613 if ret == 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
614 ret = signal.SIGTERM << 8
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
615 killdaemons()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
616 return ret
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
617
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
618 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
619 output = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
620 proc.tochild.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
621 output = proc.fromchild.read()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
622 ret = proc.wait()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
623 if wifexited(ret):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
624 ret = os.WEXITSTATUS(ret)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
625 except Timeout:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
626 vlog('# Process %d timed out - killing it' % proc.pid)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
627 ret = cleanup()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
628 output += ("\n### Abort: timeout after %d seconds.\n"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
629 % options.timeout)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
630 except KeyboardInterrupt:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
631 vlog('# Handling keyboard interrupt')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
632 cleanup()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
633 raise
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
634
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
635 for s, r in replacements:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
636 output = re.sub(s, r, output)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
637 return ret, splitnewlines(output)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
638
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
639 def runone(options, test, skips, fails):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
640 '''tristate output:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
641 None -> skipped
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
642 True -> passed
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
643 False -> failed'''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
644
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
645 def skip(msg):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
646 if not options.verbose:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
647 skips.append((test, msg))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
648 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
649 print "\nSkipping %s: %s" % (testpath, msg)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
650 return None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
651
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
652 def fail(msg):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
653 fails.append((test, msg))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
654 if not options.nodiff:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
655 print "\nERROR: %s %s" % (testpath, msg)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
656 return None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
657
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
658 vlog("# Test", test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
659
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
660 # create a fresh hgrc
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
661 hgrc = open(HGRCPATH, 'w+')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
662 hgrc.write('[ui]\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
663 hgrc.write('slash = True\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
664 hgrc.write('[defaults]\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
665 hgrc.write('backout = -d "0 0"\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
666 hgrc.write('commit = -d "0 0"\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
667 hgrc.write('tag = -d "0 0"\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
668 if options.inotify:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
669 hgrc.write('[extensions]\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
670 hgrc.write('inotify=\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
671 hgrc.write('[inotify]\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
672 hgrc.write('pidfile=%s\n' % DAEMON_PIDS)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
673 hgrc.write('appendpid=True\n')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
674 hgrc.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
675
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
676 testpath = os.path.join(TESTDIR, test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
677 ref = os.path.join(TESTDIR, test+".out")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
678 err = os.path.join(TESTDIR, test+".err")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
679 if os.path.exists(err):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
680 os.remove(err) # Remove any previous output files
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
681 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
682 tf = open(testpath)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
683 firstline = tf.readline().rstrip()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
684 tf.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
685 except:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
686 firstline = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
687 lctest = test.lower()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
688
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
689 if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
690 runner = pytest
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
691 elif lctest.endswith('.t'):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
692 runner = tsttest
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
693 ref = testpath
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
694 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
695 # do not try to run non-executable programs
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
696 if not os.access(testpath, os.X_OK):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
697 return skip("not executable")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
698 runner = shtest
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
699
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
700 # Make a tmp subdirectory to work in
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
701 testtmp = os.environ["TESTTMP"] = os.path.join(HGTMP, test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
702 os.mkdir(testtmp)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
703 os.chdir(testtmp)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
704
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
705 if options.timeout > 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
706 signal.alarm(options.timeout)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
707
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
708 ret, out = runner(testpath, options, [
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
709 (re.escape(testtmp), '$TESTTMP'),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
710 (r':%s\b' % options.port, ':$HGPORT'),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
711 (r':%s\b' % (options.port + 1), ':$HGPORT1'),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
712 (r':%s\b' % (options.port + 2), ':$HGPORT2'),
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
713 ])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
714 vlog("# Ret was:", ret)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
715
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
716 if options.timeout > 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
717 signal.alarm(0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
718
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
719 mark = '.'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
720
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
721 skipped = (ret == SKIPPED_STATUS)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
722
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
723 # If we're not in --debug mode and reference output file exists,
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
724 # check test output against it.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
725 if options.debug:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
726 refout = None # to match "out is None"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
727 elif os.path.exists(ref):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
728 f = open(ref, "r")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
729 refout = splitnewlines(f.read())
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
730 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
731 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
732 refout = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
733
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
734 if (ret != 0 or out != refout) and not skipped and not options.debug:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
735 # Save errors to a file for diagnosis
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
736 f = open(err, "wb")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
737 for line in out:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
738 f.write(line)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
739 f.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
740
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
741 if skipped:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
742 mark = 's'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
743 if out is None: # debug mode: nothing to parse
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
744 missing = ['unknown']
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
745 failed = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
746 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
747 missing, failed = parsehghaveoutput(out)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
748 if not missing:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
749 missing = ['irrelevant']
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
750 if failed:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
751 fail("hghave failed checking for %s" % failed[-1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
752 skipped = False
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
753 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
754 skip(missing[-1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
755 elif out != refout:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
756 mark = '!'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
757 if ret:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
758 fail("output changed and returned error code %d" % ret)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
759 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
760 fail("output changed")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
761 if not options.nodiff:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
762 if options.view:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
763 os.system("%s %s %s" % (options.view, ref, err))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
764 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
765 showdiff(refout, out, ref, err)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
766 ret = 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
767 elif ret:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
768 mark = '!'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
769 fail("returned error code %d" % ret)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
770
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
771 if not options.verbose:
21
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
772 try:
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
773 sys.stdout.write(mark)
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
774 sys.stdout.flush()
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
775 except IOError, ex:
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
776 print >>sys.stderr, 'BORKEN PIPE', ex.errno
aa0870d093b8 Add pull and push support for relevant heads.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 0
diff changeset
777 pass
0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
778
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
779 killdaemons()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
780
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
781 os.chdir(TESTDIR)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
782 if not options.keep_tmpdir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
783 shutil.rmtree(testtmp, True)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
784 if skipped:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
785 return None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
786 return ret == 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
787
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
788 _hgpath = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
789
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
790 def _gethgpath():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
791 """Return the path to the mercurial package that is actually found by
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
792 the current Python interpreter."""
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
793 global _hgpath
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
794 if _hgpath is not None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
795 return _hgpath
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
796
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
797 cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
798 pipe = os.popen(cmd % PYTHON)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
799 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
800 _hgpath = pipe.read().strip()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
801 finally:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
802 pipe.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
803 return _hgpath
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
804
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
805 def _checkhglib(verb):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
806 """Ensure that the 'mercurial' package imported by python is
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
807 the one we expect it to be. If not, print a warning to stderr."""
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
808 expecthg = os.path.join(PYTHONDIR, 'mercurial')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
809 actualhg = _gethgpath()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
810 if actualhg != expecthg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
811 sys.stderr.write('warning: %s with unexpected mercurial lib: %s\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
812 ' (expected %s)\n'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
813 % (verb, actualhg, expecthg))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
814
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
815 def runchildren(options, tests):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
816 if INST:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
817 installhg(options)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
818 _checkhglib("Testing")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
819
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
820 optcopy = dict(options.__dict__)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
821 optcopy['jobs'] = 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
822 del optcopy['blacklist']
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
823 if optcopy['with_hg'] is None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
824 optcopy['with_hg'] = os.path.join(BINDIR, "hg")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
825 optcopy.pop('anycoverage', None)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
826
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
827 opts = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
828 for opt, value in optcopy.iteritems():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
829 name = '--' + opt.replace('_', '-')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
830 if value is True:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
831 opts.append(name)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
832 elif value is not None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
833 opts.append(name + '=' + str(value))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
834
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
835 tests.reverse()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
836 jobs = [[] for j in xrange(options.jobs)]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
837 while tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
838 for job in jobs:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
839 if not tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
840 break
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
841 job.append(tests.pop())
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
842 fps = {}
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
843
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
844 for j, job in enumerate(jobs):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
845 if not job:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
846 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
847 rfd, wfd = os.pipe()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
848 childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
849 childtmp = os.path.join(HGTMP, 'child%d' % j)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
850 childopts += ['--tmpdir', childtmp]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
851 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
852 vlog(' '.join(cmdline))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
853 fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
854 os.close(wfd)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
855 signal.signal(signal.SIGINT, signal.SIG_IGN)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
856 failures = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
857 tested, skipped, failed = 0, 0, 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
858 skips = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
859 fails = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
860 while fps:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
861 pid, status = os.wait()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
862 fp = fps.pop(pid)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
863 l = fp.read().splitlines()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
864 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
865 test, skip, fail = map(int, l[:3])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
866 except ValueError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
867 test, skip, fail = 0, 0, 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
868 split = -fail or len(l)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
869 for s in l[3:split]:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
870 skips.append(s.split(" ", 1))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
871 for s in l[split:]:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
872 fails.append(s.split(" ", 1))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
873 tested += test
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
874 skipped += skip
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
875 failed += fail
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
876 vlog('pid %d exited, status %d' % (pid, status))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
877 failures |= status
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
878 print
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
879 if not options.noskips:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
880 for s in skips:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
881 print "Skipped %s: %s" % (s[0], s[1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
882 for s in fails:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
883 print "Failed %s: %s" % (s[0], s[1])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
884
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
885 _checkhglib("Tested")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
886 print "# Ran %d tests, %d skipped, %d failed." % (
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
887 tested, skipped, failed)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
888
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
889 if options.anycoverage:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
890 outputcoverage(options)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
891 sys.exit(failures != 0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
892
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
893 def runtests(options, tests):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
894 global DAEMON_PIDS, HGRCPATH
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
895 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
896 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
897
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
898 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
899 if INST:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
900 installhg(options)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
901 _checkhglib("Testing")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
902
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
903 if options.timeout > 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
904 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
905 signal.signal(signal.SIGALRM, alarmed)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
906 vlog('# Running each test with %d second timeout' %
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
907 options.timeout)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
908 except AttributeError:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
909 print 'WARNING: cannot run tests with timeouts'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
910 options.timeout = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
911
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
912 tested = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
913 failed = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
914 skipped = 0
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
915
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
916 if options.restart:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
917 orig = list(tests)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
918 while tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
919 if os.path.exists(tests[0] + ".err"):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
920 break
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
921 tests.pop(0)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
922 if not tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
923 print "running all tests"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
924 tests = orig
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
925
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
926 skips = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
927 fails = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
928
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
929 for test in tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
930 if options.blacklist:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
931 filename = options.blacklist.get(test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
932 if filename is not None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
933 skips.append((test, "blacklisted (%s)" % filename))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
934 skipped += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
935 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
936
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
937 if options.retest and not os.path.exists(test + ".err"):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
938 skipped += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
939 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
940
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
941 if options.keywords:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
942 fp = open(test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
943 t = fp.read().lower() + test.lower()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
944 fp.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
945 for k in options.keywords.lower().split():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
946 if k in t:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
947 break
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
948 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
949 skipped += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
950 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
951
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
952 ret = runone(options, test, skips, fails)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
953 if ret is None:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
954 skipped += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
955 elif not ret:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
956 if options.interactive:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
957 print "Accept this change? [n] ",
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
958 answer = sys.stdin.readline().strip()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
959 if answer.lower() in "y yes".split():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
960 if test.endswith(".t"):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
961 rename(test + ".err", test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
962 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
963 rename(test + ".err", test + ".out")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
964 tested += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
965 fails.pop()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
966 continue
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
967 failed += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
968 if options.first:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
969 break
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
970 tested += 1
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
971
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
972 if options.child:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
973 fp = os.fdopen(options.child, 'w')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
974 fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
975 for s in skips:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
976 fp.write("%s %s\n" % s)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
977 for s in fails:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
978 fp.write("%s %s\n" % s)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
979 fp.close()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
980 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
981 print
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
982 for s in skips:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
983 print "Skipped %s: %s" % s
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
984 for s in fails:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
985 print "Failed %s: %s" % s
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
986 _checkhglib("Tested")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
987 print "# Ran %d tests, %d skipped, %d failed." % (
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
988 tested, skipped, failed)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
989
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
990 if options.anycoverage:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
991 outputcoverage(options)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
992 except KeyboardInterrupt:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
993 failed = True
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
994 print "\ninterrupted!"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
995
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
996 if failed:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
997 sys.exit(1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
998
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
999 def main():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1000 (options, args) = parseargs()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1001 if not options.child:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1002 os.umask(022)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1003
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1004 checktools()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1005
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1006 if len(args) == 0:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1007 args = os.listdir(".")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1008 args.sort()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1009
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1010 tests = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1011 skipped = []
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1012 for test in args:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1013 if (test.startswith("test-") and '~' not in test and
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1014 ('.' not in test or test.endswith('.py') or
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1015 test.endswith('.bat') or test.endswith('.t'))):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1016 if not os.path.exists(test):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1017 skipped.append(test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1018 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1019 tests.append(test)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1020 if not tests:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1021 for test in skipped:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1022 print 'Skipped %s: does not exist' % test
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1023 print "# Ran 0 tests, %d skipped, 0 failed." % len(skipped)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1024 return
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1025 tests = tests + skipped
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1026
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1027 # Reset some environment variables to well-known values so that
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1028 # the tests produce repeatable output.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1029 os.environ['LANG'] = os.environ['LC_ALL'] = os.environ['LANGUAGE'] = 'C'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1030 os.environ['TZ'] = 'GMT'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1031 os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1032 os.environ['CDPATH'] = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1033 os.environ['COLUMNS'] = '80'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1034 os.environ['GREP_OPTIONS'] = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1035 os.environ['http_proxy'] = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1036
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1037 # unset env related to hooks
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1038 for k in os.environ.keys():
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1039 if k.startswith('HG_'):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1040 # can't remove on solaris
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1041 os.environ[k] = ''
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1042 del os.environ[k]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1043
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1044 global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1045 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1046 if options.tmpdir:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1047 options.keep_tmpdir = True
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1048 tmpdir = options.tmpdir
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1049 if os.path.exists(tmpdir):
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1050 # Meaning of tmpdir has changed since 1.3: we used to create
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1051 # HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1052 # tmpdir already exists.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1053 sys.exit("error: temp dir %r already exists" % tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1054
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1055 # Automatically removing tmpdir sounds convenient, but could
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1056 # really annoy anyone in the habit of using "--tmpdir=/tmp"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1057 # or "--tmpdir=$HOME".
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1058 #vlog("# Removing temp dir", tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1059 #shutil.rmtree(tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1060 os.makedirs(tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1061 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1062 tmpdir = tempfile.mkdtemp('', 'hgtests.')
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1063 HGTMP = os.environ['HGTMP'] = os.path.realpath(tmpdir)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1064 DAEMON_PIDS = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1065 HGRCPATH = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1066
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1067 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1068 os.environ["HGMERGE"] = "internal:merge"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1069 os.environ["HGUSER"] = "test"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1070 os.environ["HGENCODING"] = "ascii"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1071 os.environ["HGENCODINGMODE"] = "strict"
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1072 os.environ["HGPORT"] = str(options.port)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1073 os.environ["HGPORT1"] = str(options.port + 1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1074 os.environ["HGPORT2"] = str(options.port + 2)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1075
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1076 if options.with_hg:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1077 INST = None
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1078 BINDIR = os.path.dirname(os.path.realpath(options.with_hg))
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1079
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1080 # This looks redundant with how Python initializes sys.path from
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1081 # the location of the script being executed. Needed because the
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1082 # "hg" specified by --with-hg is not the only Python script
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1083 # executed in the test suite that needs to import 'mercurial'
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1084 # ... which means it's not really redundant at all.
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1085 PYTHONDIR = BINDIR
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1086 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1087 INST = os.path.join(HGTMP, "install")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1088 BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1089 PYTHONDIR = os.path.join(INST, "lib", "python")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1090
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1091 os.environ["BINDIR"] = BINDIR
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1092 os.environ["PYTHON"] = PYTHON
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1093
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1094 if not options.child:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1095 path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1096 os.environ["PATH"] = os.pathsep.join(path)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1097
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1098 # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1099 # can run .../tests/run-tests.py test-foo where test-foo
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1100 # adds an extension to HGRC
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1101 pypath = [PYTHONDIR, TESTDIR]
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1102 # We have to augment PYTHONPATH, rather than simply replacing
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1103 # it, in case external libraries are only available via current
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1104 # PYTHONPATH. (In particular, the Subversion bindings on OS X
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1105 # are in /opt/subversion.)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1106 oldpypath = os.environ.get(IMPL_PATH)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1107 if oldpypath:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1108 pypath.append(oldpypath)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1109 os.environ[IMPL_PATH] = os.pathsep.join(pypath)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1110
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1111 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1112
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1113 vlog("# Using TESTDIR", TESTDIR)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1114 vlog("# Using HGTMP", HGTMP)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1115 vlog("# Using PATH", os.environ["PATH"])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1116 vlog("# Using", IMPL_PATH, os.environ[IMPL_PATH])
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1117
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1118 try:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1119 if len(tests) > 1 and options.jobs > 1:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1120 runchildren(options, tests)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1121 else:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1122 runtests(options, tests)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1123 finally:
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1124 time.sleep(1)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1125 cleanup(options)
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1126
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1127 if __name__ == '__main__':
bbeef801409c minimalistic state concept.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
1128 main()