Show More
@@ -7,6 +7,38 b'' | |||||
7 | # This software may be used and distributed according to the terms of the |
|
7 | # This software may be used and distributed according to the terms of the | |
8 | # GNU General Public License version 2, incorporated herein by reference. |
|
8 | # GNU General Public License version 2, incorporated herein by reference. | |
9 |
|
9 | |||
|
10 | # Modifying this script is tricky because it has many modes: | |||
|
11 | # - serial (default) vs parallel (-jN, N > 1) | |||
|
12 | # - no coverage (default) vs coverage (-c, -C, -s) | |||
|
13 | # - temp install (default) vs specific hg script (--with-hg, --local) | |||
|
14 | # - tests are a mix of shell scripts and Python scripts | |||
|
15 | # | |||
|
16 | # If you change this script, it is recommended that you ensure you | |||
|
17 | # haven't broken it by running it in various modes with a representative | |||
|
18 | # sample of test scripts. For example: | |||
|
19 | # | |||
|
20 | # 1) serial, no coverage, temp install: | |||
|
21 | # ./run-tests.py test-s* | |||
|
22 | # 2) serial, no coverage, local hg: | |||
|
23 | # ./run-tests.py --local test-s* | |||
|
24 | # 3) serial, coverage, temp install: | |||
|
25 | # ./run-tests.py -c test-s* | |||
|
26 | # 4) serial, coverage, local hg: | |||
|
27 | # ./run-tests.py -c --local test-s* # unsupported | |||
|
28 | # 5) parallel, no coverage, temp install: | |||
|
29 | # ./run-tests.py -j2 test-s* | |||
|
30 | # 6) parallel, no coverage, local hg: | |||
|
31 | # ./run-tests.py -j2 --local test-s* | |||
|
32 | # 7) parallel, coverage, temp install: | |||
|
33 | # ./run-tests.py -j2 -c test-s* # currently broken | |||
|
34 | # 8) parallel, coverage, local install | |||
|
35 | # ./run-tests.py -j2 -c --local test-s* # unsupported (and broken) | |||
|
36 | # | |||
|
37 | # (You could use any subset of the tests: test-s* happens to match | |||
|
38 | # enough that it's worth doing parallel runs, few enough that it | |||
|
39 | # completes fairly quickly, includes both shell and Python scripts, and | |||
|
40 | # includes some scripts that run daemon processes.) | |||
|
41 | ||||
10 | import difflib |
|
42 | import difflib | |
11 | import errno |
|
43 | import errno | |
12 | import optparse |
|
44 | import optparse | |
@@ -34,7 +66,6 b' SKIPPED_STATUS = 80' | |||||
34 | SKIPPED_PREFIX = 'skipped: ' |
|
66 | SKIPPED_PREFIX = 'skipped: ' | |
35 | FAILED_PREFIX = 'hghave check failed: ' |
|
67 | FAILED_PREFIX = 'hghave check failed: ' | |
36 | PYTHON = sys.executable |
|
68 | PYTHON = sys.executable | |
37 | hgpkg = None |
|
|||
38 |
|
69 | |||
39 | requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] |
|
70 | requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] | |
40 |
|
71 | |||
@@ -81,7 +112,11 b' def parseargs():' | |||||
81 | parser.add_option("-n", "--nodiff", action="store_true", |
|
112 | parser.add_option("-n", "--nodiff", action="store_true", | |
82 | help="skip showing test changes") |
|
113 | help="skip showing test changes") | |
83 | parser.add_option("--with-hg", type="string", |
|
114 | parser.add_option("--with-hg", type="string", | |
84 | help="test existing install at given location") |
|
115 | metavar="HG", | |
|
116 | help="test using specified hg script rather than a " | |||
|
117 | "temporary installation") | |||
|
118 | parser.add_option("--local", action="store_true", | |||
|
119 | help="shortcut for --with-hg=<testdir>/../hg") | |||
85 | parser.add_option("--pure", action="store_true", |
|
120 | parser.add_option("--pure", action="store_true", | |
86 | help="use pure Python code instead of C extensions") |
|
121 | help="use pure Python code instead of C extensions") | |
87 |
|
122 | |||
@@ -90,11 +125,32 b' def parseargs():' | |||||
90 | parser.set_defaults(**defaults) |
|
125 | parser.set_defaults(**defaults) | |
91 | (options, args) = parser.parse_args() |
|
126 | (options, args) = parser.parse_args() | |
92 |
|
127 | |||
93 | global vlog |
|
128 | if options.with_hg: | |
|
129 | if not (os.path.isfile(options.with_hg) and | |||
|
130 | os.access(options.with_hg, os.X_OK)): | |||
|
131 | parser.error('--with-hg must specify an executable hg script') | |||
|
132 | if not os.path.basename(options.with_hg) == 'hg': | |||
|
133 | sys.stderr.write('warning: --with-hg should specify an hg script') | |||
|
134 | if options.local: | |||
|
135 | testdir = os.path.dirname(os.path.realpath(sys.argv[0])) | |||
|
136 | hgbin = os.path.join(os.path.dirname(testdir), 'hg') | |||
|
137 | if not os.access(hgbin, os.X_OK): | |||
|
138 | parser.error('--local specified, but %r not found or not executable' | |||
|
139 | % hgbin) | |||
|
140 | options.with_hg = hgbin | |||
|
141 | ||||
94 | options.anycoverage = (options.cover or |
|
142 | options.anycoverage = (options.cover or | |
95 | options.cover_stdlib or |
|
143 | options.cover_stdlib or | |
96 | options.annotate) |
|
144 | options.annotate) | |
97 |
|
145 | |||
|
146 | if options.anycoverage and options.with_hg: | |||
|
147 | # I'm not sure if this is a fundamental limitation or just a | |||
|
148 | # bug. But I don't want to waste people's time and energy doing | |||
|
149 | # test runs that don't give the results they want. | |||
|
150 | parser.error("sorry, coverage options do not work when --with-hg " | |||
|
151 | "or --local specified") | |||
|
152 | ||||
|
153 | global vlog | |||
98 | if options.verbose: |
|
154 | if options.verbose: | |
99 | if options.jobs > 1 or options.child is not None: |
|
155 | if options.jobs > 1 or options.child is not None: | |
100 | pid = "[%d]" % os.getpid() |
|
156 | pid = "[%d]" % os.getpid() | |
@@ -227,16 +283,6 b' def installhg(options):' | |||||
227 | sys.exit(1) |
|
283 | sys.exit(1) | |
228 | os.chdir(TESTDIR) |
|
284 | os.chdir(TESTDIR) | |
229 |
|
285 | |||
230 | os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"]) |
|
|||
231 |
|
||||
232 | pydir = os.pathsep.join([PYTHONDIR, TESTDIR]) |
|
|||
233 | pythonpath = os.environ.get("PYTHONPATH") |
|
|||
234 | if pythonpath: |
|
|||
235 | pythonpath = pydir + os.pathsep + pythonpath |
|
|||
236 | else: |
|
|||
237 | pythonpath = pydir |
|
|||
238 | os.environ["PYTHONPATH"] = pythonpath |
|
|||
239 |
|
||||
240 | usecorrectpython() |
|
286 | usecorrectpython() | |
241 |
|
287 | |||
242 | vlog("# Installing dummy diffstat") |
|
288 | vlog("# Installing dummy diffstat") | |
@@ -512,13 +558,14 b' def _checkhglib(verb):' | |||||
512 | % (verb, actualhg, expecthg)) |
|
558 | % (verb, actualhg, expecthg)) | |
513 |
|
559 | |||
514 | def runchildren(options, tests): |
|
560 | def runchildren(options, tests): | |
515 | if not options.with_hg: |
|
561 | if INST: | |
516 | installhg(options) |
|
562 | installhg(options) | |
517 | _checkhglib("Testing") |
|
563 | _checkhglib("Testing") | |
518 |
|
564 | |||
519 | optcopy = dict(options.__dict__) |
|
565 | optcopy = dict(options.__dict__) | |
520 | optcopy['jobs'] = 1 |
|
566 | optcopy['jobs'] = 1 | |
521 |
optcopy['with_hg'] |
|
567 | if optcopy['with_hg'] is None: | |
|
568 | optcopy['with_hg'] = os.path.join(BINDIR, "hg") | |||
522 | opts = [] |
|
569 | opts = [] | |
523 | for opt, value in optcopy.iteritems(): |
|
570 | for opt, value in optcopy.iteritems(): | |
524 | name = '--' + opt.replace('_', '-') |
|
571 | name = '--' + opt.replace('_', '-') | |
@@ -579,7 +626,7 b' def runtests(options, tests):' | |||||
579 | HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc') |
|
626 | HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc') | |
580 |
|
627 | |||
581 | try: |
|
628 | try: | |
582 | if not options.with_hg: |
|
629 | if INST: | |
583 | installhg(options) |
|
630 | installhg(options) | |
584 | _checkhglib("Testing") |
|
631 | _checkhglib("Testing") | |
585 |
|
632 | |||
@@ -687,11 +734,31 b' def main():' | |||||
687 | os.environ["HGPORT2"] = str(options.port + 2) |
|
734 | os.environ["HGPORT2"] = str(options.port + 2) | |
688 |
|
735 | |||
689 | if options.with_hg: |
|
736 | if options.with_hg: | |
690 |
INST = |
|
737 | INST = None | |
|
738 | BINDIR = os.path.dirname(os.path.realpath(options.with_hg)) | |||
|
739 | ||||
|
740 | # This looks redundant with how Python initializes sys.path from | |||
|
741 | # the location of the script being executed. Needed because the | |||
|
742 | # "hg" specified by --with-hg is not the only Python script | |||
|
743 | # executed in the test suite that needs to import 'mercurial' | |||
|
744 | # ... which means it's not really redundant at all. | |||
|
745 | PYTHONDIR = BINDIR | |||
691 | else: |
|
746 | else: | |
692 | INST = os.path.join(HGTMP, "install") |
|
747 | INST = os.path.join(HGTMP, "install") | |
693 | BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin") |
|
748 | BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin") | |
694 | PYTHONDIR = os.path.join(INST, "lib", "python") |
|
749 | PYTHONDIR = os.path.join(INST, "lib", "python") | |
|
750 | ||||
|
751 | os.environ["BINDIR"] = BINDIR | |||
|
752 | os.environ["PYTHON"] = PYTHON | |||
|
753 | ||||
|
754 | if not options.child: | |||
|
755 | path = [BINDIR] + os.environ["PATH"].split(os.pathsep) | |||
|
756 | os.environ["PATH"] = os.pathsep.join(path) | |||
|
757 | ||||
|
758 | # Deliberately override existing PYTHONPATH: do not want success | |||
|
759 | # to depend on what happens to be in caller's environment. | |||
|
760 | os.environ["PYTHONPATH"] = PYTHONDIR | |||
|
761 | ||||
695 | COVERAGE_FILE = os.path.join(TESTDIR, ".coverage") |
|
762 | COVERAGE_FILE = os.path.join(TESTDIR, ".coverage") | |
696 |
|
763 | |||
697 | if len(args) == 0: |
|
764 | if len(args) == 0: | |
@@ -710,6 +777,8 b' def main():' | |||||
710 |
|
777 | |||
711 | vlog("# Using TESTDIR", TESTDIR) |
|
778 | vlog("# Using TESTDIR", TESTDIR) | |
712 | vlog("# Using HGTMP", HGTMP) |
|
779 | vlog("# Using HGTMP", HGTMP) | |
|
780 | vlog("# Using PATH", os.environ["PATH"]) | |||
|
781 | vlog("# Using PYTHONPATH", os.environ["PYTHONPATH"]) | |||
713 |
|
782 | |||
714 | try: |
|
783 | try: | |
715 | if len(tests) > 1 and options.jobs > 1: |
|
784 | if len(tests) > 1 and options.jobs > 1: |
@@ -47,4 +47,6 b' hg convert --debug --filemap filemap a p' | |||||
47 |
|
47 | |||
48 | echo % converting empty dir should fail "nicely" |
|
48 | echo % converting empty dir should fail "nicely" | |
49 | mkdir emptydir |
|
49 | mkdir emptydir | |
50 | PATH=$BINDIR hg convert emptydir 2>&1 | sed 's,file://.*/emptydir,.../emptydir,g' |
|
50 | # override $PATH to ensure p4 not visible; use $PYTHON in case we're | |
|
51 | # running from a devel copy, not a temp installation | |||
|
52 | PATH=$BINDIR $PYTHON $BINDIR/hg convert emptydir 2>&1 | sed 's,file://.*/emptydir,.../emptydir,g' |
@@ -60,7 +60,9 b' echo' | |||||
60 | echo "# default is internal merge:" |
|
60 | echo "# default is internal merge:" | |
61 | beforemerge |
|
61 | beforemerge | |
62 | echo "# hg merge -r 2" |
|
62 | echo "# hg merge -r 2" | |
63 | PATH=$BINDIR hg merge -r 2 |
|
63 | # override $PATH to ensure hgmerge not visible; use $PYTHON in case we're | |
|
64 | # running from a devel copy, not a temp installation | |||
|
65 | PATH=$BINDIR $PYTHON $BINDIR/hg merge -r 2 | |||
64 | aftermerge |
|
66 | aftermerge | |
65 |
|
67 | |||
66 | echo "# simplest hgrc using false for merge:" |
|
68 | echo "# simplest hgrc using false for merge:" |
General Comments 0
You need to be logged in to leave comments.
Login now