##// END OF EJS Templates
test-gendoc: test documentation generation
Martin Geisler -
r9446:57d682d7 default
parent child Browse files
Show More
@@ -0,0 +1,12 b''
1 #!/bin/sh
2
3 "$TESTDIR/hghave" rst2html || exit 80
4 RST2HTML=$(which rst2html 2> /dev/null || which rst2html.py)
5
6 echo "checking for syntax errors in gendoc.py"
7 python $TESTDIR/../doc/gendoc.py > gendoc.txt || exit
8
9 # We run rst2html over the file without adding "--halt warning" to
10 # make it report all errors instead of stopping on the first one.
11 echo "checking for parse errors with rst2html"
12 $RST2HTML gendoc.txt /dev/null
@@ -0,0 +1,2 b''
1 checking for syntax errors in gendoc.py
2 checking for parse errors with rst2html
@@ -1,272 +1,277 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """Test the running system for features availability. Exit with zero
2 """Test the running system for features availability. Exit with zero
3 if all features are there, non-zero otherwise. If a feature name is
3 if all features are there, non-zero otherwise. If a feature name is
4 prefixed with "no-", the absence of feature is tested.
4 prefixed with "no-", the absence of feature is tested.
5 """
5 """
6 import optparse
6 import optparse
7 import os
7 import os
8 import re
8 import re
9 import sys
9 import sys
10 import tempfile
10 import tempfile
11
11
12 tempprefix = 'hg-hghave-'
12 tempprefix = 'hg-hghave-'
13
13
14 def matchoutput(cmd, regexp, ignorestatus=False):
14 def matchoutput(cmd, regexp, ignorestatus=False):
15 """Return True if cmd executes successfully and its output
15 """Return True if cmd executes successfully and its output
16 is matched by the supplied regular expression.
16 is matched by the supplied regular expression.
17 """
17 """
18 r = re.compile(regexp)
18 r = re.compile(regexp)
19 fh = os.popen(cmd)
19 fh = os.popen(cmd)
20 s = fh.read()
20 s = fh.read()
21 try:
21 try:
22 ret = fh.close()
22 ret = fh.close()
23 except IOError:
23 except IOError:
24 # Happen in Windows test environment
24 # Happen in Windows test environment
25 ret = 1
25 ret = 1
26 return (ignorestatus or ret is None) and r.search(s)
26 return (ignorestatus or ret is None) and r.search(s)
27
27
28 def has_baz():
28 def has_baz():
29 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
29 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
30
30
31 def has_bzr():
31 def has_bzr():
32 try:
32 try:
33 import bzrlib
33 import bzrlib
34 return bzrlib.__doc__ != None
34 return bzrlib.__doc__ != None
35 except ImportError:
35 except ImportError:
36 return False
36 return False
37
37
38 def has_bzr114():
38 def has_bzr114():
39 try:
39 try:
40 import bzrlib
40 import bzrlib
41 return (bzrlib.__doc__ != None
41 return (bzrlib.__doc__ != None
42 and bzrlib.version_info[:2] >= (1, 14))
42 and bzrlib.version_info[:2] >= (1, 14))
43 except ImportError:
43 except ImportError:
44 return False
44 return False
45
45
46 def has_cvs():
46 def has_cvs():
47 re = r'Concurrent Versions System.*?server'
47 re = r'Concurrent Versions System.*?server'
48 return matchoutput('cvs --version 2>&1', re)
48 return matchoutput('cvs --version 2>&1', re)
49
49
50 def has_cvsps():
50 def has_cvsps():
51 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
51 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
52
52
53 def has_darcs():
53 def has_darcs():
54 return matchoutput('darcs --version', r'2\.[2-9]', True)
54 return matchoutput('darcs --version', r'2\.[2-9]', True)
55
55
56 def has_mtn():
56 def has_mtn():
57 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
57 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
58 'mtn --version', r'monotone 0\.(\d|[12]\d|3[01])[^\d]', True)
58 'mtn --version', r'monotone 0\.(\d|[12]\d|3[01])[^\d]', True)
59
59
60 def has_eol_in_paths():
60 def has_eol_in_paths():
61 try:
61 try:
62 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
62 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
63 os.close(fd)
63 os.close(fd)
64 os.remove(path)
64 os.remove(path)
65 return True
65 return True
66 except:
66 except:
67 return False
67 return False
68
68
69 def has_executablebit():
69 def has_executablebit():
70 fd, path = tempfile.mkstemp(prefix=tempprefix)
70 fd, path = tempfile.mkstemp(prefix=tempprefix)
71 os.close(fd)
71 os.close(fd)
72 try:
72 try:
73 s = os.lstat(path).st_mode
73 s = os.lstat(path).st_mode
74 os.chmod(path, s | 0100)
74 os.chmod(path, s | 0100)
75 return (os.lstat(path).st_mode & 0100 != 0)
75 return (os.lstat(path).st_mode & 0100 != 0)
76 finally:
76 finally:
77 os.remove(path)
77 os.remove(path)
78
78
79 def has_icasefs():
79 def has_icasefs():
80 # Stolen from mercurial.util
80 # Stolen from mercurial.util
81 fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
81 fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
82 os.close(fd)
82 os.close(fd)
83 try:
83 try:
84 s1 = os.stat(path)
84 s1 = os.stat(path)
85 d, b = os.path.split(path)
85 d, b = os.path.split(path)
86 p2 = os.path.join(d, b.upper())
86 p2 = os.path.join(d, b.upper())
87 if path == p2:
87 if path == p2:
88 p2 = os.path.join(d, b.lower())
88 p2 = os.path.join(d, b.lower())
89 try:
89 try:
90 s2 = os.stat(p2)
90 s2 = os.stat(p2)
91 return s2 == s1
91 return s2 == s1
92 except:
92 except:
93 return False
93 return False
94 finally:
94 finally:
95 os.remove(path)
95 os.remove(path)
96
96
97 def has_inotify():
97 def has_inotify():
98 try:
98 try:
99 import hgext.inotify.linux.watcher
99 import hgext.inotify.linux.watcher
100 return True
100 return True
101 except ImportError:
101 except ImportError:
102 return False
102 return False
103
103
104 def has_fifo():
104 def has_fifo():
105 return hasattr(os, "mkfifo")
105 return hasattr(os, "mkfifo")
106
106
107 def has_hotshot():
107 def has_hotshot():
108 try:
108 try:
109 # hotshot.stats tests hotshot and many problematic dependencies
109 # hotshot.stats tests hotshot and many problematic dependencies
110 # like profile.
110 # like profile.
111 import hotshot.stats
111 import hotshot.stats
112 return True
112 return True
113 except ImportError:
113 except ImportError:
114 return False
114 return False
115
115
116 def has_lsprof():
116 def has_lsprof():
117 try:
117 try:
118 import _lsprof
118 import _lsprof
119 return True
119 return True
120 except ImportError:
120 except ImportError:
121 return False
121 return False
122
122
123 def has_git():
123 def has_git():
124 return matchoutput('git --version 2>&1', r'^git version')
124 return matchoutput('git --version 2>&1', r'^git version')
125
125
126 def has_rst2html():
127 return matchoutput('rst2html --version', r'^rst2html \(Docutils') or \
128 matchoutput('rst2html.py --version', r'^rst2html.py \(Docutils')
129
126 def has_svn():
130 def has_svn():
127 return matchoutput('svn --version 2>&1', r'^svn, version') and \
131 return matchoutput('svn --version 2>&1', r'^svn, version') and \
128 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
132 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
129
133
130 def has_svn_bindings():
134 def has_svn_bindings():
131 try:
135 try:
132 import svn.core
136 import svn.core
133 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
137 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
134 if version < (1, 4):
138 if version < (1, 4):
135 return False
139 return False
136 return True
140 return True
137 except ImportError:
141 except ImportError:
138 return False
142 return False
139
143
140 def has_p4():
144 def has_p4():
141 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
145 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
142
146
143 def has_symlink():
147 def has_symlink():
144 return hasattr(os, "symlink")
148 return hasattr(os, "symlink")
145
149
146 def has_tla():
150 def has_tla():
147 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
151 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
148
152
149 def has_gpg():
153 def has_gpg():
150 return matchoutput('gpg --version 2>&1', r'GnuPG')
154 return matchoutput('gpg --version 2>&1', r'GnuPG')
151
155
152 def has_unix_permissions():
156 def has_unix_permissions():
153 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
157 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
154 try:
158 try:
155 fname = os.path.join(d, 'foo')
159 fname = os.path.join(d, 'foo')
156 for umask in (077, 007, 022):
160 for umask in (077, 007, 022):
157 os.umask(umask)
161 os.umask(umask)
158 f = open(fname, 'w')
162 f = open(fname, 'w')
159 f.close()
163 f.close()
160 mode = os.stat(fname).st_mode
164 mode = os.stat(fname).st_mode
161 os.unlink(fname)
165 os.unlink(fname)
162 if mode & 0777 != ~umask & 0666:
166 if mode & 0777 != ~umask & 0666:
163 return False
167 return False
164 return True
168 return True
165 finally:
169 finally:
166 os.rmdir(d)
170 os.rmdir(d)
167
171
168 def has_pygments():
172 def has_pygments():
169 try:
173 try:
170 import pygments
174 import pygments
171 return True
175 return True
172 except ImportError:
176 except ImportError:
173 return False
177 return False
174
178
175 def has_outer_repo():
179 def has_outer_repo():
176 return matchoutput('hg root 2>&1', r'')
180 return matchoutput('hg root 2>&1', r'')
177
181
178 checks = {
182 checks = {
179 "baz": (has_baz, "GNU Arch baz client"),
183 "baz": (has_baz, "GNU Arch baz client"),
180 "bzr": (has_bzr, "Canonical's Bazaar client"),
184 "bzr": (has_bzr, "Canonical's Bazaar client"),
181 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
185 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
182 "cvs": (has_cvs, "cvs client/server"),
186 "cvs": (has_cvs, "cvs client/server"),
183 "cvsps": (has_cvsps, "cvsps utility"),
187 "cvsps": (has_cvsps, "cvsps utility"),
184 "darcs": (has_darcs, "darcs client"),
188 "darcs": (has_darcs, "darcs client"),
185 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
189 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
186 "execbit": (has_executablebit, "executable bit"),
190 "execbit": (has_executablebit, "executable bit"),
187 "fifo": (has_fifo, "named pipes"),
191 "fifo": (has_fifo, "named pipes"),
188 "git": (has_git, "git command line client"),
192 "git": (has_git, "git command line client"),
189 "gpg": (has_gpg, "gpg client"),
193 "gpg": (has_gpg, "gpg client"),
190 "hotshot": (has_hotshot, "python hotshot module"),
194 "hotshot": (has_hotshot, "python hotshot module"),
191 "icasefs": (has_icasefs, "case insensitive file system"),
195 "icasefs": (has_icasefs, "case insensitive file system"),
192 "inotify": (has_inotify, "inotify extension support"),
196 "inotify": (has_inotify, "inotify extension support"),
193 "lsprof": (has_lsprof, "python lsprof module"),
197 "lsprof": (has_lsprof, "python lsprof module"),
194 "mtn": (has_mtn, "monotone client (> 0.31)"),
198 "mtn": (has_mtn, "monotone client (> 0.31)"),
195 "outer-repo": (has_outer_repo, "outer repo"),
199 "outer-repo": (has_outer_repo, "outer repo"),
196 "p4": (has_p4, "Perforce server and client"),
200 "p4": (has_p4, "Perforce server and client"),
197 "pygments": (has_pygments, "Pygments source highlighting library"),
201 "pygments": (has_pygments, "Pygments source highlighting library"),
202 "rst2html": (has_rst2html, "Docutils rst2html tool"),
198 "svn": (has_svn, "subversion client and admin tools"),
203 "svn": (has_svn, "subversion client and admin tools"),
199 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
204 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
200 "symlink": (has_symlink, "symbolic links"),
205 "symlink": (has_symlink, "symbolic links"),
201 "tla": (has_tla, "GNU Arch tla client"),
206 "tla": (has_tla, "GNU Arch tla client"),
202 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
207 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
203 }
208 }
204
209
205 def list_features():
210 def list_features():
206 for name, feature in checks.iteritems():
211 for name, feature in checks.iteritems():
207 desc = feature[1]
212 desc = feature[1]
208 print name + ':', desc
213 print name + ':', desc
209
214
210 def test_features():
215 def test_features():
211 failed = 0
216 failed = 0
212 for name, feature in checks.iteritems():
217 for name, feature in checks.iteritems():
213 check, _ = feature
218 check, _ = feature
214 try:
219 try:
215 check()
220 check()
216 except Exception, e:
221 except Exception, e:
217 print "feature %s failed: %s" % (name, e)
222 print "feature %s failed: %s" % (name, e)
218 failed += 1
223 failed += 1
219 return failed
224 return failed
220
225
221 parser = optparse.OptionParser("%prog [options] [features]")
226 parser = optparse.OptionParser("%prog [options] [features]")
222 parser.add_option("--test-features", action="store_true",
227 parser.add_option("--test-features", action="store_true",
223 help="test available features")
228 help="test available features")
224 parser.add_option("--list-features", action="store_true",
229 parser.add_option("--list-features", action="store_true",
225 help="list available features")
230 help="list available features")
226 parser.add_option("-q", "--quiet", action="store_true",
231 parser.add_option("-q", "--quiet", action="store_true",
227 help="check features silently")
232 help="check features silently")
228
233
229 if __name__ == '__main__':
234 if __name__ == '__main__':
230 options, args = parser.parse_args()
235 options, args = parser.parse_args()
231 if options.list_features:
236 if options.list_features:
232 list_features()
237 list_features()
233 sys.exit(0)
238 sys.exit(0)
234
239
235 if options.test_features:
240 if options.test_features:
236 sys.exit(test_features())
241 sys.exit(test_features())
237
242
238 quiet = options.quiet
243 quiet = options.quiet
239
244
240 failures = 0
245 failures = 0
241
246
242 def error(msg):
247 def error(msg):
243 global failures
248 global failures
244 if not quiet:
249 if not quiet:
245 sys.stderr.write(msg + '\n')
250 sys.stderr.write(msg + '\n')
246 failures += 1
251 failures += 1
247
252
248 for feature in args:
253 for feature in args:
249 negate = feature.startswith('no-')
254 negate = feature.startswith('no-')
250 if negate:
255 if negate:
251 feature = feature[3:]
256 feature = feature[3:]
252
257
253 if feature not in checks:
258 if feature not in checks:
254 error('skipped: unknown feature: ' + feature)
259 error('skipped: unknown feature: ' + feature)
255 continue
260 continue
256
261
257 check, desc = checks[feature]
262 check, desc = checks[feature]
258 try:
263 try:
259 available = check()
264 available = check()
260 except Exception, e:
265 except Exception, e:
261 error('hghave check failed: ' + feature)
266 error('hghave check failed: ' + feature)
262 continue
267 continue
263
268
264 if not negate and not available:
269 if not negate and not available:
265 error('skipped: missing feature: ' + desc)
270 error('skipped: missing feature: ' + desc)
266 elif negate and available:
271 elif negate and available:
267 error('skipped: system supports %s' % desc)
272 error('skipped: system supports %s' % desc)
268
273
269 if failures != 0:
274 if failures != 0:
270 sys.exit(1)
275 sys.exit(1)
271
276
272
277
General Comments 0
You need to be logged in to leave comments. Login now