##// END OF EJS Templates
tests/hghave: bzr114 checks for bzr >= 1.14...
Mads Kiilerich -
r9244:3f52a709 default
parent child Browse files
Show More
@@ -1,272 +1,272 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', r'darcs version', True)
54 return matchoutput('darcs', r'darcs version', 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)
81 fd, path = tempfile.mkstemp(prefix=tempprefix)
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_svn():
126 def has_svn():
127 return matchoutput('svn --version 2>&1', r'^svn, version') and \
127 return matchoutput('svn --version 2>&1', r'^svn, version') and \
128 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
128 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
129
129
130 def has_svn_bindings():
130 def has_svn_bindings():
131 try:
131 try:
132 import svn.core
132 import svn.core
133 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
133 version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
134 if version < (1, 4):
134 if version < (1, 4):
135 return False
135 return False
136 return True
136 return True
137 except ImportError:
137 except ImportError:
138 return False
138 return False
139
139
140 def has_p4():
140 def has_p4():
141 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
141 return matchoutput('p4 -V', r'Rev\. P4/') and matchoutput('p4d -V', r'Rev\. P4D/')
142
142
143 def has_symlink():
143 def has_symlink():
144 return hasattr(os, "symlink")
144 return hasattr(os, "symlink")
145
145
146 def has_tla():
146 def has_tla():
147 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
147 return matchoutput('tla --version 2>&1', r'The GNU Arch Revision')
148
148
149 def has_gpg():
149 def has_gpg():
150 return matchoutput('gpg --version 2>&1', r'GnuPG')
150 return matchoutput('gpg --version 2>&1', r'GnuPG')
151
151
152 def has_unix_permissions():
152 def has_unix_permissions():
153 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
153 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
154 try:
154 try:
155 fname = os.path.join(d, 'foo')
155 fname = os.path.join(d, 'foo')
156 for umask in (077, 007, 022):
156 for umask in (077, 007, 022):
157 os.umask(umask)
157 os.umask(umask)
158 f = open(fname, 'w')
158 f = open(fname, 'w')
159 f.close()
159 f.close()
160 mode = os.stat(fname).st_mode
160 mode = os.stat(fname).st_mode
161 os.unlink(fname)
161 os.unlink(fname)
162 if mode & 0777 != ~umask & 0666:
162 if mode & 0777 != ~umask & 0666:
163 return False
163 return False
164 return True
164 return True
165 finally:
165 finally:
166 os.rmdir(d)
166 os.rmdir(d)
167
167
168 def has_pygments():
168 def has_pygments():
169 try:
169 try:
170 import pygments
170 import pygments
171 return True
171 return True
172 except ImportError:
172 except ImportError:
173 return False
173 return False
174
174
175 def has_outer_repo():
175 def has_outer_repo():
176 return matchoutput('hg root 2>&1', r'')
176 return matchoutput('hg root 2>&1', r'')
177
177
178 checks = {
178 checks = {
179 "baz": (has_baz, "GNU Arch baz client"),
179 "baz": (has_baz, "GNU Arch baz client"),
180 "bzr": (has_bzr, "Canonical's Bazaar client"),
180 "bzr": (has_bzr, "Canonical's Bazaar client"),
181 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
181 "bzr114": (has_bzr114, "Canonical's Bazaar client >= 1.14"),
182 "cvs": (has_cvs, "cvs client/server"),
182 "cvs": (has_cvs, "cvs client/server"),
183 "cvsps": (has_cvsps, "cvsps utility"),
183 "cvsps": (has_cvsps, "cvsps utility"),
184 "darcs": (has_darcs, "darcs client"),
184 "darcs": (has_darcs, "darcs client"),
185 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
185 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
186 "execbit": (has_executablebit, "executable bit"),
186 "execbit": (has_executablebit, "executable bit"),
187 "fifo": (has_fifo, "named pipes"),
187 "fifo": (has_fifo, "named pipes"),
188 "git": (has_git, "git command line client"),
188 "git": (has_git, "git command line client"),
189 "gpg": (has_gpg, "gpg client"),
189 "gpg": (has_gpg, "gpg client"),
190 "hotshot": (has_hotshot, "python hotshot module"),
190 "hotshot": (has_hotshot, "python hotshot module"),
191 "icasefs": (has_icasefs, "case insensitive file system"),
191 "icasefs": (has_icasefs, "case insensitive file system"),
192 "inotify": (has_inotify, "inotify extension support"),
192 "inotify": (has_inotify, "inotify extension support"),
193 "lsprof": (has_lsprof, "python lsprof module"),
193 "lsprof": (has_lsprof, "python lsprof module"),
194 "mtn": (has_mtn, "monotone client (> 0.31)"),
194 "mtn": (has_mtn, "monotone client (> 0.31)"),
195 "outer-repo": (has_outer_repo, "outer repo"),
195 "outer-repo": (has_outer_repo, "outer repo"),
196 "p4": (has_p4, "Perforce server and client"),
196 "p4": (has_p4, "Perforce server and client"),
197 "pygments": (has_pygments, "Pygments source highlighting library"),
197 "pygments": (has_pygments, "Pygments source highlighting library"),
198 "svn": (has_svn, "subversion client and admin tools"),
198 "svn": (has_svn, "subversion client and admin tools"),
199 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
199 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
200 "symlink": (has_symlink, "symbolic links"),
200 "symlink": (has_symlink, "symbolic links"),
201 "tla": (has_tla, "GNU Arch tla client"),
201 "tla": (has_tla, "GNU Arch tla client"),
202 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
202 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
203 }
203 }
204
204
205 def list_features():
205 def list_features():
206 for name, feature in checks.iteritems():
206 for name, feature in checks.iteritems():
207 desc = feature[1]
207 desc = feature[1]
208 print name + ':', desc
208 print name + ':', desc
209
209
210 def test_features():
210 def test_features():
211 failed = 0
211 failed = 0
212 for name, feature in checks.iteritems():
212 for name, feature in checks.iteritems():
213 check, _ = feature
213 check, _ = feature
214 try:
214 try:
215 check()
215 check()
216 except Exception, e:
216 except Exception, e:
217 print "feature %s failed: %s" % (name, e)
217 print "feature %s failed: %s" % (name, e)
218 failed += 1
218 failed += 1
219 return failed
219 return failed
220
220
221 parser = optparse.OptionParser("%prog [options] [features]")
221 parser = optparse.OptionParser("%prog [options] [features]")
222 parser.add_option("--test-features", action="store_true",
222 parser.add_option("--test-features", action="store_true",
223 help="test available features")
223 help="test available features")
224 parser.add_option("--list-features", action="store_true",
224 parser.add_option("--list-features", action="store_true",
225 help="list available features")
225 help="list available features")
226 parser.add_option("-q", "--quiet", action="store_true",
226 parser.add_option("-q", "--quiet", action="store_true",
227 help="check features silently")
227 help="check features silently")
228
228
229 if __name__ == '__main__':
229 if __name__ == '__main__':
230 options, args = parser.parse_args()
230 options, args = parser.parse_args()
231 if options.list_features:
231 if options.list_features:
232 list_features()
232 list_features()
233 sys.exit(0)
233 sys.exit(0)
234
234
235 if options.test_features:
235 if options.test_features:
236 sys.exit(test_features())
236 sys.exit(test_features())
237
237
238 quiet = options.quiet
238 quiet = options.quiet
239
239
240 failures = 0
240 failures = 0
241
241
242 def error(msg):
242 def error(msg):
243 global failures
243 global failures
244 if not quiet:
244 if not quiet:
245 sys.stderr.write(msg + '\n')
245 sys.stderr.write(msg + '\n')
246 failures += 1
246 failures += 1
247
247
248 for feature in args:
248 for feature in args:
249 negate = feature.startswith('no-')
249 negate = feature.startswith('no-')
250 if negate:
250 if negate:
251 feature = feature[3:]
251 feature = feature[3:]
252
252
253 if feature not in checks:
253 if feature not in checks:
254 error('skipped: unknown feature: ' + feature)
254 error('skipped: unknown feature: ' + feature)
255 continue
255 continue
256
256
257 check, desc = checks[feature]
257 check, desc = checks[feature]
258 try:
258 try:
259 available = check()
259 available = check()
260 except Exception, e:
260 except Exception, e:
261 error('hghave check failed: ' + feature)
261 error('hghave check failed: ' + feature)
262 continue
262 continue
263
263
264 if not negate and not available:
264 if not negate and not available:
265 error('skipped: missing feature: ' + desc)
265 error('skipped: missing feature: ' + desc)
266 elif negate and available:
266 elif negate and available:
267 error('skipped: system supports %s' % desc)
267 error('skipped: system supports %s' % desc)
268
268
269 if failures != 0:
269 if failures != 0:
270 sys.exit(1)
270 sys.exit(1)
271
271
272
272
General Comments 0
You need to be logged in to leave comments. Login now