##// END OF EJS Templates
run-tests: move diff generation into TestResult...
Gregory Szorc -
r21521:855f092c default
parent child Browse files
Show More
@@ -282,16 +282,16 b' def rename(src, dst):'
282 shutil.copy(src, dst)
282 shutil.copy(src, dst)
283 os.remove(src)
283 os.remove(src)
284
284
285 def showdiff(expected, output, ref, err):
285 def getdiff(expected, output, ref, err):
286 print
287 servefail = False
286 servefail = False
287 lines = []
288 for line in difflib.unified_diff(expected, output, ref, err):
288 for line in difflib.unified_diff(expected, output, ref, err):
289 sys.stdout.write(line)
289 lines.append(line)
290 if not servefail and line.startswith(
290 if not servefail and line.startswith(
291 '+ abort: child process failed to start'):
291 '+ abort: child process failed to start'):
292 servefail = True
292 servefail = True
293 return {'servefail': servefail}
294
293
294 return servefail, lines
295
295
296 verbose = False
296 verbose = False
297 def vlog(*msg):
297 def vlog(*msg):
@@ -339,7 +339,7 b' class Test(unittest.TestCase):'
339 SKIPPED_STATUS = 80
339 SKIPPED_STATUS = 80
340
340
341 def __init__(self, path, tmpdir, keeptmpdir=False,
341 def __init__(self, path, tmpdir, keeptmpdir=False,
342 debug=False, nodiff=False, diffviewer=None,
342 debug=False,
343 interactive=False, timeout=defaults['timeout'],
343 interactive=False, timeout=defaults['timeout'],
344 startport=defaults['port'], extraconfigopts=None,
344 startport=defaults['port'], extraconfigopts=None,
345 py3kwarnings=False, shell=None):
345 py3kwarnings=False, shell=None):
@@ -355,11 +355,6 b' class Test(unittest.TestCase):'
355 debug mode will make the test execute verbosely, with unfiltered
355 debug mode will make the test execute verbosely, with unfiltered
356 output.
356 output.
357
357
358 nodiff will suppress the printing of a diff when output changes.
359
360 diffviewer is the program that should be used to display diffs. Only
361 used when output changes.
362
363 interactive controls whether the test will run interactively.
358 interactive controls whether the test will run interactively.
364
359
365 timeout controls the maximum run time of the test. It is ignored when
360 timeout controls the maximum run time of the test. It is ignored when
@@ -387,8 +382,6 b' class Test(unittest.TestCase):'
387 self._threadtmp = tmpdir
382 self._threadtmp = tmpdir
388 self._keeptmpdir = keeptmpdir
383 self._keeptmpdir = keeptmpdir
389 self._debug = debug
384 self._debug = debug
390 self._nodiff = nodiff
391 self._diffviewer = diffviewer
392 self._interactive = interactive
385 self._interactive = interactive
393 self._timeout = timeout
386 self._timeout = timeout
394 self._startport = startport
387 self._startport = startport
@@ -408,8 +401,8 b' class Test(unittest.TestCase):'
408 # check test output against it.
401 # check test output against it.
409 if debug:
402 if debug:
410 self._refout = None # to match "out is None"
403 self._refout = None # to match "out is None"
411 elif os.path.exists(self._refpath):
404 elif os.path.exists(self.refpath):
412 f = open(self._refpath, 'r')
405 f = open(self.refpath, 'r')
413 self._refout = f.read().splitlines(True)
406 self._refout = f.read().splitlines(True)
414 f.close()
407 f.close()
415 else:
408 else:
@@ -443,6 +436,7 b' class Test(unittest.TestCase):'
443 os.remove(self.errpath)
436 os.remove(self.errpath)
444
437
445 def run(self, result):
438 def run(self, result):
439 self._result = result
446 result.startTest(self)
440 result.startTest(self)
447 try:
441 try:
448 try:
442 try:
@@ -533,23 +527,13 b' class Test(unittest.TestCase):'
533 elif ret == 'timeout':
527 elif ret == 'timeout':
534 self.fail('timed out', ret)
528 self.fail('timed out', ret)
535 elif out != self._refout:
529 elif out != self._refout:
536 info = {}
530 # The result object handles diff calculation for us.
537 if not self._nodiff:
531 self._result.addOutputMismatch(self, out, self._refout)
538 iolock.acquire()
532
539 if self._diffviewer:
540 os.system("%s %s %s" % (self._diffviewer, self._refpath,
541 self.errpath))
542 else:
543 info = showdiff(self._refout, out, self._refpath,
544 self.errpath)
545 iolock.release()
546 msg = ''
547 if info.get('servefail'):
548 msg += 'serve failed and '
549 if ret:
533 if ret:
550 msg += 'output changed and ' + describe(ret)
534 msg = 'output changed and ' + describe(ret)
551 else:
535 else:
552 msg += 'output changed'
536 msg = 'output changed'
553
537
554 if (ret != 0 or out != self._refout) and not self._skipped \
538 if (ret != 0 or out != self._refout) and not self._skipped \
555 and not self._debug:
539 and not self._debug:
@@ -661,9 +645,6 b' class Test(unittest.TestCase):'
661
645
662 def fail(self, msg, ret):
646 def fail(self, msg, ret):
663 warned = ret is False
647 warned = ret is False
664 if not self._nodiff:
665 log("\n%s: %s %s" % (warned and 'Warning' or 'ERROR', self.name,
666 msg))
667 if (not ret and self._interactive and
648 if (not ret and self._interactive and
668 os.path.exists(self.errpath)):
649 os.path.exists(self.errpath)):
669 iolock.acquire()
650 iolock.acquire()
@@ -689,7 +670,7 b' class PythonTest(Test):'
689 """A Python-based test."""
670 """A Python-based test."""
690
671
691 @property
672 @property
692 def _refpath(self):
673 def refpath(self):
693 return os.path.join(self._testdir, '%s.out' % self.name)
674 return os.path.join(self._testdir, '%s.out' % self.name)
694
675
695 def _run(self, replacements, env):
676 def _run(self, replacements, env):
@@ -717,7 +698,7 b' class TTest(Test):'
717 {'\\': '\\\\', '\r': r'\r'})
698 {'\\': '\\\\', '\r': r'\r'})
718
699
719 @property
700 @property
720 def _refpath(self):
701 def refpath(self):
721 return os.path.join(self._testdir, self.name)
702 return os.path.join(self._testdir, self.name)
722
703
723 def _run(self, replacements, env):
704 def _run(self, replacements, env):
@@ -1140,6 +1121,25 b' class TestResult(unittest._TextTestResul'
1140 self.stream.write('~')
1121 self.stream.write('~')
1141 self.stream.flush()
1122 self.stream.flush()
1142
1123
1124 def addOutputMismatch(self, test, got, expected):
1125 """Record a mismatch in test output for a particular test."""
1126
1127 if self._options.nodiff:
1128 return
1129
1130 if self._options.view:
1131 os.system("%s %s %s" % (self._view, test.refpath, test.errpath))
1132 else:
1133 failed, lines = getdiff(expected, got,
1134 test.refpath, test.errpath)
1135 if failed:
1136 self.addFailure(test, 'diff generation failed')
1137 else:
1138 self.stream.write('\n')
1139 for line in lines:
1140 self.stream.write(line)
1141 self.stream.flush()
1142
1143 def startTest(self, test):
1143 def startTest(self, test):
1144 super(TestResult, self).startTest(test)
1144 super(TestResult, self).startTest(test)
1145
1145
@@ -1526,8 +1526,6 b' class TestRunner(object):'
1526 return testcls(refpath, tmpdir,
1526 return testcls(refpath, tmpdir,
1527 keeptmpdir=self.options.keep_tmpdir,
1527 keeptmpdir=self.options.keep_tmpdir,
1528 debug=self.options.debug,
1528 debug=self.options.debug,
1529 nodiff = self.options.nodiff,
1530 diffviewer=self.options.view,
1531 interactive=self.options.interactive,
1529 interactive=self.options.interactive,
1532 timeout=self.options.timeout,
1530 timeout=self.options.timeout,
1533 startport=self.options.port + count * 3,
1531 startport=self.options.port + count * 3,
General Comments 0
You need to be logged in to leave comments. Login now