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