102 'timeout': ('HGTEST_TIMEOUT', 180), |
102 'timeout': ('HGTEST_TIMEOUT', 180), |
103 'port': ('HGTEST_PORT', 20059), |
103 'port': ('HGTEST_PORT', 20059), |
104 'shell': ('HGTEST_SHELL', '/bin/sh'), |
104 'shell': ('HGTEST_SHELL', '/bin/sh'), |
105 } |
105 } |
106 |
106 |
|
107 def parselistfiles(files, listtype, warn=True): |
|
108 entries = dict() |
|
109 for filename in files: |
|
110 try: |
|
111 path = os.path.expanduser(os.path.expandvars(filename)) |
|
112 f = open(path, "r") |
|
113 except IOError, err: |
|
114 if err.errno != errno.ENOENT: |
|
115 raise |
|
116 if warn: |
|
117 print "warning: no such %s file: %s" % (listtype, filename) |
|
118 continue |
|
119 |
|
120 for line in f.readlines(): |
|
121 line = line.split('#', 1)[0].strip() |
|
122 if line: |
|
123 entries[line] = filename |
|
124 |
|
125 f.close() |
|
126 return entries |
|
127 |
107 def parseargs(): |
128 def parseargs(): |
108 parser = optparse.OptionParser("%prog [options] [tests]") |
129 parser = optparse.OptionParser("%prog [options] [tests]") |
109 |
130 |
110 # keep these sorted |
131 # keep these sorted |
111 parser.add_option("--blacklist", action="append", |
132 parser.add_option("--blacklist", action="append", |
112 help="skip tests listed in the specified blacklist file") |
133 help="skip tests listed in the specified blacklist file") |
|
134 parser.add_option("--whitelist", action="append", |
|
135 help="always run tests listed in the specified whitelist file") |
113 parser.add_option("-C", "--annotate", action="store_true", |
136 parser.add_option("-C", "--annotate", action="store_true", |
114 help="output files annotated with coverage") |
137 help="output files annotated with coverage") |
115 parser.add_option("--child", type="int", |
138 parser.add_option("--child", type="int", |
116 help="run as child process, summary to given fd") |
139 help="run as child process, summary to given fd") |
117 parser.add_option("-c", "--cover", action="store_true", |
140 parser.add_option("-c", "--cover", action="store_true", |
245 options.timeout = 0 |
268 options.timeout = 0 |
246 if options.py3k_warnings: |
269 if options.py3k_warnings: |
247 if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): |
270 if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): |
248 parser.error('--py3k-warnings can only be used on Python 2.6+') |
271 parser.error('--py3k-warnings can only be used on Python 2.6+') |
249 if options.blacklist: |
272 if options.blacklist: |
250 blacklist = dict() |
273 options.blacklist = parselistfiles(options.blacklist, 'blacklist') |
251 for filename in options.blacklist: |
274 if options.whitelist: |
252 try: |
275 options.whitelisted = parselistfiles(options.whitelist, 'whitelist', |
253 path = os.path.expanduser(os.path.expandvars(filename)) |
276 warn=options.child is None) |
254 f = open(path, "r") |
277 else: |
255 except IOError, err: |
278 options.whitelisted = {} |
256 if err.errno != errno.ENOENT: |
|
257 raise |
|
258 print "warning: no such blacklist file: %s" % filename |
|
259 continue |
|
260 |
|
261 for line in f.readlines(): |
|
262 line = line.split('#', 1)[0].strip() |
|
263 if line: |
|
264 blacklist[line] = filename |
|
265 |
|
266 f.close() |
|
267 |
|
268 options.blacklist = blacklist |
|
269 |
279 |
270 return (options, args) |
280 return (options, args) |
271 |
281 |
272 def rename(src, dst): |
282 def rename(src, dst): |
273 """Like os.rename(), trade atomicity and opened files friendliness |
283 """Like os.rename(), trade atomicity and opened files friendliness |
731 skip("doesn't exist") |
741 skip("doesn't exist") |
732 return None |
742 return None |
733 else: |
743 else: |
734 return None # not a supported test, don't record |
744 return None # not a supported test, don't record |
735 |
745 |
736 if options.blacklist and test in options.blacklist: |
746 if not (options.whitelisted and test in options.whitelisted): |
737 skip("blacklisted") |
747 if options.blacklist and test in options.blacklist: |
738 return None |
748 skip("blacklisted") |
739 |
749 return None |
740 if options.retest and not os.path.exists(test + ".err"): |
750 |
741 ignore("not retesting") |
751 if options.retest and not os.path.exists(test + ".err"): |
742 return None |
752 ignore("not retesting") |
743 |
753 return None |
744 if options.keywords: |
754 |
745 fp = open(test) |
755 if options.keywords: |
746 t = fp.read().lower() + test.lower() |
756 fp = open(test) |
747 fp.close() |
757 t = fp.read().lower() + test.lower() |
748 for k in options.keywords.lower().split(): |
758 fp.close() |
749 if k in t: |
759 for k in options.keywords.lower().split(): |
750 break |
760 if k in t: |
751 else: |
761 break |
752 ignore("doesn't match keyword") |
762 else: |
753 return None |
763 ignore("doesn't match keyword") |
|
764 return None |
754 |
765 |
755 vlog("# Test", test) |
766 vlog("# Test", test) |
756 |
767 |
757 # create a fresh hgrc |
768 # create a fresh hgrc |
758 hgrc = open(HGRCPATH, 'w+') |
769 hgrc = open(HGRCPATH, 'w+') |
918 _checkhglib("Testing") |
929 _checkhglib("Testing") |
919 |
930 |
920 optcopy = dict(options.__dict__) |
931 optcopy = dict(options.__dict__) |
921 optcopy['jobs'] = 1 |
932 optcopy['jobs'] = 1 |
922 |
933 |
|
934 # Because whitelist has to override keyword matches, we have to |
|
935 # actually load the whitelist in the children as well, so we allow |
|
936 # the list of whitelist files to pass through and be parsed in the |
|
937 # children, but not the dict of whitelisted tests resulting from |
|
938 # the parse, used here to override blacklisted tests. |
|
939 whitelist = optcopy['whitelisted'] or [] |
|
940 del optcopy['whitelisted'] |
|
941 |
923 blacklist = optcopy['blacklist'] or [] |
942 blacklist = optcopy['blacklist'] or [] |
924 del optcopy['blacklist'] |
943 del optcopy['blacklist'] |
925 blacklisted = [] |
944 blacklisted = [] |
926 |
945 |
927 if optcopy['with_hg'] is None: |
946 if optcopy['with_hg'] is None: |