comparison tests/run-tests.py @ 4881:c51c9bc4579d

Add hghave utility and run-tests.py support. hghave detects system features like symlinks availability at run-time. Tests can be skipped by starting them with: "$TESTDIR/hghave" symlink || exit 80 The 80 exit status triggers hghave output handling by run-tests.py. Also, tests output can be locally patched on the fly to match reference output.
author Patrick Mezard <pmezard@gmail.com>
date Sat, 14 Jul 2007 18:34:06 +0200
parents 6403f948bd6b
children d27ed83289ee
comparison
equal deleted inserted replaced
4880:6403f948bd6b 4881:c51c9bc4579d
16 import shutil 16 import shutil
17 import signal 17 import signal
18 import sys 18 import sys
19 import tempfile 19 import tempfile
20 import time 20 import time
21
22 # hghave reserved exit code to skip test
23 SKIPPED_STATUS = 80
21 24
22 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] 25 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
23 26
24 parser = optparse.OptionParser("%prog [options] [tests]") 27 parser = optparse.OptionParser("%prog [options] [tests]")
25 parser.add_option("-v", "--verbose", action="store_true", 28 parser.add_option("-v", "--verbose", action="store_true",
65 if last: 68 if last:
66 lines.append(last) 69 lines.append(last)
67 return lines 70 return lines
68 lines.append(text[i:n+1]) 71 lines.append(text[i:n+1])
69 i = n + 1 72 i = n + 1
73
74 def extract_missing_features(lines):
75 '''Extract missing/unknown features log lines as a list'''
76 missing = []
77 for line in lines:
78 if not line.startswith('hghave: '):
79 continue
80 line = line.splitlines()[0]
81 missing.append(line[8:])
82
83 return missing
70 84
71 def show_diff(expected, output): 85 def show_diff(expected, output):
72 for line in difflib.unified_diff(expected, output, 86 for line in difflib.unified_diff(expected, output,
73 "Expected output", "Test output"): 87 "Expected output", "Test output"):
74 sys.stdout.write(line) 88 sys.stdout.write(line)
281 vlog("# Ret was:", ret) 295 vlog("# Ret was:", ret)
282 296
283 if options.timeout > 0: 297 if options.timeout > 0:
284 signal.alarm(0) 298 signal.alarm(0)
285 299
300 skipped = (ret == SKIPPED_STATUS)
286 diffret = 0 301 diffret = 0
287 # If reference output file exists, check test output against it 302 # If reference output file exists, check test output against it
288 if os.path.exists(ref): 303 if os.path.exists(ref):
289 f = open(ref, "r") 304 f = open(ref, "r")
290 ref_out = splitnewlines(f.read()) 305 ref_out = splitnewlines(f.read())
291 f.close() 306 f.close()
292 else: 307 else:
293 ref_out = [] 308 ref_out = []
294 if out != ref_out: 309 if not skipped and out != ref_out:
295 diffret = 1 310 diffret = 1
296 print "\nERROR: %s output changed" % (test) 311 print "\nERROR: %s output changed" % (test)
297 show_diff(ref_out, out) 312 show_diff(ref_out, out)
298 if ret: 313 if skipped:
314 missing = extract_missing_features(out)
315 if not missing:
316 missing = ['irrelevant']
317 print '\nSkipping %s: %s' % (test, missing[-1])
318 elif ret:
299 print "\nERROR: %s failed with error code %d" % (test, ret) 319 print "\nERROR: %s failed with error code %d" % (test, ret)
300 elif diffret: 320 elif diffret:
301 ret = diffret 321 ret = diffret
302 322
303 if ret != 0: # Save errors to a file for diagnosis 323 if ret != 0 and not skipped:
324 # Save errors to a file for diagnosis
304 f = open(err, "wb") 325 f = open(err, "wb")
305 for line in out: 326 for line in out:
306 f.write(line) 327 f.write(line)
307 f.close() 328 f.close()
308 329
330 except IOError: 351 except IOError:
331 pass 352 pass
332 353
333 os.chdir(TESTDIR) 354 os.chdir(TESTDIR)
334 shutil.rmtree(tmpd, True) 355 shutil.rmtree(tmpd, True)
356 if skipped:
357 return None
335 return ret == 0 358 return ret == 0
336 359
337 360
338 os.umask(022) 361 os.umask(022)
339 362