##// END OF EJS Templates
tests: skip cvs tests with msys on windows...
Mads Kiilerich -
r15568:08635f4e default
parent child Browse files
Show More
@@ -1,329 +1,329 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) and not has_msys()
49
49
50 def has_darcs():
50 def has_darcs():
51 return matchoutput('darcs --version', r'2\.[2-9]', True)
51 return matchoutput('darcs --version', r'2\.[2-9]', True)
52
52
53 def has_mtn():
53 def has_mtn():
54 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
54 return matchoutput('mtn --version', r'monotone', True) and not matchoutput(
55 'mtn --version', r'monotone 0\.', True)
55 'mtn --version', r'monotone 0\.', True)
56
56
57 def has_eol_in_paths():
57 def has_eol_in_paths():
58 try:
58 try:
59 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
59 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
60 os.close(fd)
60 os.close(fd)
61 os.remove(path)
61 os.remove(path)
62 return True
62 return True
63 except:
63 except:
64 return False
64 return False
65
65
66 def has_executablebit():
66 def has_executablebit():
67 fd, path = tempfile.mkstemp(prefix=tempprefix)
67 fd, path = tempfile.mkstemp(prefix=tempprefix)
68 os.close(fd)
68 os.close(fd)
69 try:
69 try:
70 s = os.lstat(path).st_mode
70 s = os.lstat(path).st_mode
71 os.chmod(path, s | 0100)
71 os.chmod(path, s | 0100)
72 return (os.lstat(path).st_mode & 0100 != 0)
72 return (os.lstat(path).st_mode & 0100 != 0)
73 finally:
73 finally:
74 os.remove(path)
74 os.remove(path)
75
75
76 def has_icasefs():
76 def has_icasefs():
77 # Stolen from mercurial.util
77 # Stolen from mercurial.util
78 fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
78 fd, path = tempfile.mkstemp(prefix=tempprefix, dir='.')
79 os.close(fd)
79 os.close(fd)
80 try:
80 try:
81 s1 = os.stat(path)
81 s1 = os.stat(path)
82 d, b = os.path.split(path)
82 d, b = os.path.split(path)
83 p2 = os.path.join(d, b.upper())
83 p2 = os.path.join(d, b.upper())
84 if path == p2:
84 if path == p2:
85 p2 = os.path.join(d, b.lower())
85 p2 = os.path.join(d, b.lower())
86 try:
86 try:
87 s2 = os.stat(p2)
87 s2 = os.stat(p2)
88 return s2 == s1
88 return s2 == s1
89 except:
89 except:
90 return False
90 return False
91 finally:
91 finally:
92 os.remove(path)
92 os.remove(path)
93
93
94 def has_inotify():
94 def has_inotify():
95 try:
95 try:
96 import hgext.inotify.linux.watcher
96 import hgext.inotify.linux.watcher
97 return True
97 return True
98 except ImportError:
98 except ImportError:
99 return False
99 return False
100
100
101 def has_fifo():
101 def has_fifo():
102 return hasattr(os, "mkfifo")
102 return hasattr(os, "mkfifo")
103
103
104 def has_cacheable_fs():
104 def has_cacheable_fs():
105 from mercurial import util
105 from mercurial import util
106
106
107 fd, path = tempfile.mkstemp(prefix=tempprefix)
107 fd, path = tempfile.mkstemp(prefix=tempprefix)
108 os.close(fd)
108 os.close(fd)
109 try:
109 try:
110 return util.cachestat(path).cacheable()
110 return util.cachestat(path).cacheable()
111 finally:
111 finally:
112 os.remove(path)
112 os.remove(path)
113
113
114 def has_lsprof():
114 def has_lsprof():
115 try:
115 try:
116 import _lsprof
116 import _lsprof
117 return True
117 return True
118 except ImportError:
118 except ImportError:
119 return False
119 return False
120
120
121 def has_gettext():
121 def has_gettext():
122 return matchoutput('msgfmt --version', 'GNU gettext-tools')
122 return matchoutput('msgfmt --version', 'GNU gettext-tools')
123
123
124 def has_git():
124 def has_git():
125 return matchoutput('git --version 2>&1', r'^git version')
125 return matchoutput('git --version 2>&1', r'^git version')
126
126
127 def has_docutils():
127 def has_docutils():
128 try:
128 try:
129 from docutils.core import publish_cmdline
129 from docutils.core import publish_cmdline
130 return True
130 return True
131 except ImportError:
131 except ImportError:
132 return False
132 return False
133
133
134 def getsvnversion():
134 def getsvnversion():
135 m = matchoutput('svn --version 2>&1', r'^svn,\s+version\s+(\d+)\.(\d+)')
135 m = matchoutput('svn --version 2>&1', r'^svn,\s+version\s+(\d+)\.(\d+)')
136 if not m:
136 if not m:
137 return (0, 0)
137 return (0, 0)
138 return (int(m.group(1)), int(m.group(2)))
138 return (int(m.group(1)), int(m.group(2)))
139
139
140 def has_svn15():
140 def has_svn15():
141 return getsvnversion() >= (1, 5)
141 return getsvnversion() >= (1, 5)
142
142
143 def has_svn13():
143 def has_svn13():
144 return getsvnversion() >= (1, 3)
144 return getsvnversion() >= (1, 3)
145
145
146 def has_svn():
146 def has_svn():
147 return matchoutput('svn --version 2>&1', r'^svn, version') and \
147 return matchoutput('svn --version 2>&1', r'^svn, version') and \
148 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
148 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
149
149
150 def has_svn_bindings():
150 def has_svn_bindings():
151 try:
151 try:
152 import svn.core
152 import svn.core
153 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
153 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
154 if version < (1, 4):
154 if version < (1, 4):
155 return False
155 return False
156 return True
156 return True
157 except ImportError:
157 except ImportError:
158 return False
158 return False
159
159
160 def has_p4():
160 def has_p4():
161 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
161 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
162
162
163 def has_symlink():
163 def has_symlink():
164 return hasattr(os, "symlink") # FIXME: should also check file system and os
164 return hasattr(os, "symlink") # FIXME: should also check file system and os
165
165
166 def has_tla():
166 def has_tla():
167 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
167 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
168
168
169 def has_gpg():
169 def has_gpg():
170 return matchoutput('gpg --version 2>&1', r'GnuPG')
170 return matchoutput('gpg --version 2>&1', r'GnuPG')
171
171
172 def has_unix_permissions():
172 def has_unix_permissions():
173 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
173 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
174 try:
174 try:
175 fname = os.path.join(d, 'foo')
175 fname = os.path.join(d, 'foo')
176 for umask in (077, 007, 022):
176 for umask in (077, 007, 022):
177 os.umask(umask)
177 os.umask(umask)
178 f = open(fname, 'w')
178 f = open(fname, 'w')
179 f.close()
179 f.close()
180 mode = os.stat(fname).st_mode
180 mode = os.stat(fname).st_mode
181 os.unlink(fname)
181 os.unlink(fname)
182 if mode & 0777 != ~umask & 0666:
182 if mode & 0777 != ~umask & 0666:
183 return False
183 return False
184 return True
184 return True
185 finally:
185 finally:
186 os.rmdir(d)
186 os.rmdir(d)
187
187
188 def has_pyflakes():
188 def has_pyflakes():
189 return matchoutput('echo "import re" 2>&1 | pyflakes',
189 return matchoutput('echo "import re" 2>&1 | pyflakes',
190 r"<stdin>:1: 're' imported but unused",
190 r"<stdin>:1: 're' imported but unused",
191 True)
191 True)
192
192
193 def has_pygments():
193 def has_pygments():
194 try:
194 try:
195 import pygments
195 import pygments
196 return True
196 return True
197 except ImportError:
197 except ImportError:
198 return False
198 return False
199
199
200 def has_outer_repo():
200 def has_outer_repo():
201 return matchoutput('hg root 2>&1', r'')
201 return matchoutput('hg root 2>&1', r'')
202
202
203 def has_ssl():
203 def has_ssl():
204 try:
204 try:
205 import ssl
205 import ssl
206 import OpenSSL
206 import OpenSSL
207 OpenSSL.SSL.Context
207 OpenSSL.SSL.Context
208 return True
208 return True
209 except ImportError:
209 except ImportError:
210 return False
210 return False
211
211
212 def has_windows():
212 def has_windows():
213 return os.name == 'nt'
213 return os.name == 'nt'
214
214
215 def has_system_sh():
215 def has_system_sh():
216 return os.name != 'nt'
216 return os.name != 'nt'
217
217
218 def has_serve():
218 def has_serve():
219 return os.name != 'nt' # gross approximation
219 return os.name != 'nt' # gross approximation
220
220
221 def has_tic():
221 def has_tic():
222 return matchoutput('test -x "`which tic`"', '')
222 return matchoutput('test -x "`which tic`"', '')
223
223
224 def has_msys():
224 def has_msys():
225 return os.getenv('MSYSTEM')
225 return os.getenv('MSYSTEM')
226
226
227 checks = {
227 checks = {
228 "baz": (has_baz, "GNU Arch baz client"),
228 "baz": (has_baz, "GNU Arch baz client"),
229 "bzr": (has_bzr, "Canonical's Bazaar client"),
229 "bzr": (has_bzr, "Canonical's Bazaar client"),
230 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
230 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
231 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
231 "cacheable": (has_cacheable_fs, "cacheable filesystem"),
232 "cvs": (has_cvs, "cvs client/server"),
232 "cvs": (has_cvs, "cvs client/server"),
233 "darcs": (has_darcs, "darcs client"),
233 "darcs": (has_darcs, "darcs client"),
234 "docutils": (has_docutils, "Docutils text processing library"),
234 "docutils": (has_docutils, "Docutils text processing library"),
235 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
235 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
236 "execbit": (has_executablebit, "executable bit"),
236 "execbit": (has_executablebit, "executable bit"),
237 "fifo": (has_fifo, "named pipes"),
237 "fifo": (has_fifo, "named pipes"),
238 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
238 "gettext": (has_gettext, "GNU Gettext (msgfmt)"),
239 "git": (has_git, "git command line client"),
239 "git": (has_git, "git command line client"),
240 "gpg": (has_gpg, "gpg client"),
240 "gpg": (has_gpg, "gpg client"),
241 "icasefs": (has_icasefs, "case insensitive file system"),
241 "icasefs": (has_icasefs, "case insensitive file system"),
242 "inotify": (has_inotify, "inotify extension support"),
242 "inotify": (has_inotify, "inotify extension support"),
243 "lsprof": (has_lsprof, "python lsprof module"),
243 "lsprof": (has_lsprof, "python lsprof module"),
244 "mtn": (has_mtn, "monotone client (>= 1.0)"),
244 "mtn": (has_mtn, "monotone client (>= 1.0)"),
245 "outer-repo": (has_outer_repo, "outer repo"),
245 "outer-repo": (has_outer_repo, "outer repo"),
246 "p4": (has_p4, "Perforce server and client"),
246 "p4": (has_p4, "Perforce server and client"),
247 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
247 "pyflakes": (has_pyflakes, "Pyflakes python linter"),
248 "pygments": (has_pygments, "Pygments source highlighting library"),
248 "pygments": (has_pygments, "Pygments source highlighting library"),
249 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
249 "serve": (has_serve, "platform and python can manage 'hg serve -d'"),
250 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
250 "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
251 "svn": (has_svn, "subversion client and admin tools"),
251 "svn": (has_svn, "subversion client and admin tools"),
252 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
252 "svn13": (has_svn13, "subversion client and admin tools >= 1.3"),
253 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
253 "svn15": (has_svn15, "subversion client and admin tools >= 1.5"),
254 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
254 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
255 "symlink": (has_symlink, "symbolic links"),
255 "symlink": (has_symlink, "symbolic links"),
256 "system-sh": (has_system_sh, "system() uses sh"),
256 "system-sh": (has_system_sh, "system() uses sh"),
257 "tic": (has_tic, "terminfo compiler"),
257 "tic": (has_tic, "terminfo compiler"),
258 "tla": (has_tla, "GNU Arch tla client"),
258 "tla": (has_tla, "GNU Arch tla client"),
259 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
259 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
260 "windows": (has_windows, "Windows"),
260 "windows": (has_windows, "Windows"),
261 "msys": (has_msys, "Windows with MSYS"),
261 "msys": (has_msys, "Windows with MSYS"),
262 }
262 }
263
263
264 def list_features():
264 def list_features():
265 for name, feature in checks.iteritems():
265 for name, feature in checks.iteritems():
266 desc = feature[1]
266 desc = feature[1]
267 print name + ':', desc
267 print name + ':', desc
268
268
269 def test_features():
269 def test_features():
270 failed = 0
270 failed = 0
271 for name, feature in checks.iteritems():
271 for name, feature in checks.iteritems():
272 check, _ = feature
272 check, _ = feature
273 try:
273 try:
274 check()
274 check()
275 except Exception, e:
275 except Exception, e:
276 print "feature %s failed: %s" % (name, e)
276 print "feature %s failed: %s" % (name, e)
277 failed += 1
277 failed += 1
278 return failed
278 return failed
279
279
280 parser = optparse.OptionParser("%prog [options] [features]")
280 parser = optparse.OptionParser("%prog [options] [features]")
281 parser.add_option("--test-features", action="store_true",
281 parser.add_option("--test-features", action="store_true",
282 help="test available features")
282 help="test available features")
283 parser.add_option("--list-features", action="store_true",
283 parser.add_option("--list-features", action="store_true",
284 help="list available features")
284 help="list available features")
285 parser.add_option("-q", "--quiet", action="store_true",
285 parser.add_option("-q", "--quiet", action="store_true",
286 help="check features silently")
286 help="check features silently")
287
287
288 if __name__ == '__main__':
288 if __name__ == '__main__':
289 options, args = parser.parse_args()
289 options, args = parser.parse_args()
290 if options.list_features:
290 if options.list_features:
291 list_features()
291 list_features()
292 sys.exit(0)
292 sys.exit(0)
293
293
294 if options.test_features:
294 if options.test_features:
295 sys.exit(test_features())
295 sys.exit(test_features())
296
296
297 quiet = options.quiet
297 quiet = options.quiet
298
298
299 failures = 0
299 failures = 0
300
300
301 def error(msg):
301 def error(msg):
302 global failures
302 global failures
303 if not quiet:
303 if not quiet:
304 sys.stderr.write(msg + '\n')
304 sys.stderr.write(msg + '\n')
305 failures += 1
305 failures += 1
306
306
307 for feature in args:
307 for feature in args:
308 negate = feature.startswith('no-')
308 negate = feature.startswith('no-')
309 if negate:
309 if negate:
310 feature = feature[3:]
310 feature = feature[3:]
311
311
312 if feature not in checks:
312 if feature not in checks:
313 error('skipped: unknown feature: ' + feature)
313 error('skipped: unknown feature: ' + feature)
314 continue
314 continue
315
315
316 check, desc = checks[feature]
316 check, desc = checks[feature]
317 try:
317 try:
318 available = check()
318 available = check()
319 except Exception, e:
319 except Exception, e:
320 error('hghave check failed: ' + feature)
320 error('hghave check failed: ' + feature)
321 continue
321 continue
322
322
323 if not negate and not available:
323 if not negate and not available:
324 error('skipped: missing feature: ' + desc)
324 error('skipped: missing feature: ' + desc)
325 elif negate and available:
325 elif negate and available:
326 error('skipped: system supports %s' % desc)
326 error('skipped: system supports %s' % desc)
327
327
328 if failures != 0:
328 if failures != 0:
329 sys.exit(1)
329 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now