Show More
@@ -65,6 +65,7 b' def handleexception(orig, ui):' | |||||
65 | primaryframe, |
|
65 | primaryframe, | |
66 | hgframe, |
|
66 | hgframe, | |
67 | hgline, |
|
67 | hgline, | |
|
68 | ui.environ[b'TESTNAME'].decode('utf-8', 'replace'), | |||
68 | ] |
|
69 | ] | |
69 | fh.write(b'\0'.join(p.encode('utf-8', 'replace') for p in parts)) |
|
70 | fh.write(b'\0'.join(p.encode('utf-8', 'replace') for p in parts)) | |
70 |
|
71 |
@@ -1052,6 +1052,7 b' class Test(unittest.TestCase):' | |||||
1052 | env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' |
|
1052 | env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or '' | |
1053 | env['HGEMITWARNINGS'] = '1' |
|
1053 | env['HGEMITWARNINGS'] = '1' | |
1054 | env['TESTTMP'] = self._testtmp |
|
1054 | env['TESTTMP'] = self._testtmp | |
|
1055 | env['TESTNAME'] = self.name | |||
1055 | env['HOME'] = self._testtmp |
|
1056 | env['HOME'] = self._testtmp | |
1056 | # This number should match portneeded in _getport |
|
1057 | # This number should match portneeded in _getport | |
1057 | for port in xrange(3): |
|
1058 | for port in xrange(3): | |
@@ -2135,13 +2136,21 b' class TextTestRunner(unittest.TextTestRu' | |||||
2135 | if self._runner.options.exceptions: |
|
2136 | if self._runner.options.exceptions: | |
2136 | exceptions = aggregateexceptions( |
|
2137 | exceptions = aggregateexceptions( | |
2137 | os.path.join(self._runner._outputdir, b'exceptions')) |
|
2138 | os.path.join(self._runner._outputdir, b'exceptions')) | |
2138 | total = sum(exceptions.values()) |
|
|||
2139 |
|
2139 | |||
2140 | self.stream.writeln('Exceptions Report:') |
|
2140 | self.stream.writeln('Exceptions Report:') | |
2141 | self.stream.writeln('%d total from %d frames' % |
|
2141 | self.stream.writeln('%d total from %d frames' % | |
2142 |
(total, |
|
2142 | (exceptions['total'], | |
2143 | for (frame, line, exc), count in exceptions.most_common(): |
|
2143 | len(exceptions['exceptioncounts']))) | |
2144 | self.stream.writeln('%d\t%s: %s' % (count, frame, exc)) |
|
2144 | combined = exceptions['combined'] | |
|
2145 | for key in sorted(combined, key=combined.get, reverse=True): | |||
|
2146 | frame, line, exc = key | |||
|
2147 | totalcount, testcount, leastcount, leasttest = combined[key] | |||
|
2148 | ||||
|
2149 | self.stream.writeln('%d (%d tests)\t%s: %s (%s - %d total)' | |||
|
2150 | % (totalcount, | |||
|
2151 | testcount, | |||
|
2152 | frame, exc, | |||
|
2153 | leasttest, leastcount)) | |||
2145 |
|
2154 | |||
2146 | self.stream.flush() |
|
2155 | self.stream.flush() | |
2147 |
|
2156 | |||
@@ -3012,22 +3021,57 b' class TestRunner(object):' | |||||
3012 | p.decode("utf-8")) |
|
3021 | p.decode("utf-8")) | |
3013 |
|
3022 | |||
3014 | def aggregateexceptions(path): |
|
3023 | def aggregateexceptions(path): | |
3015 | exceptions = collections.Counter() |
|
3024 | exceptioncounts = collections.Counter() | |
|
3025 | testsbyfailure = collections.defaultdict(set) | |||
|
3026 | failuresbytest = collections.defaultdict(set) | |||
3016 |
|
3027 | |||
3017 | for f in os.listdir(path): |
|
3028 | for f in os.listdir(path): | |
3018 | with open(os.path.join(path, f), 'rb') as fh: |
|
3029 | with open(os.path.join(path, f), 'rb') as fh: | |
3019 | data = fh.read().split(b'\0') |
|
3030 | data = fh.read().split(b'\0') | |
3020 |
if len(data) != |
|
3031 | if len(data) != 5: | |
3021 | continue |
|
3032 | continue | |
3022 |
|
3033 | |||
3023 | exc, mainframe, hgframe, hgline = data |
|
3034 | exc, mainframe, hgframe, hgline, testname = data | |
3024 | exc = exc.decode('utf-8') |
|
3035 | exc = exc.decode('utf-8') | |
3025 | mainframe = mainframe.decode('utf-8') |
|
3036 | mainframe = mainframe.decode('utf-8') | |
3026 | hgframe = hgframe.decode('utf-8') |
|
3037 | hgframe = hgframe.decode('utf-8') | |
3027 | hgline = hgline.decode('utf-8') |
|
3038 | hgline = hgline.decode('utf-8') | |
3028 | exceptions[(hgframe, hgline, exc)] += 1 |
|
3039 | testname = testname.decode('utf-8') | |
3029 |
|
3040 | |||
3030 | return exceptions |
|
3041 | key = (hgframe, hgline, exc) | |
|
3042 | exceptioncounts[key] += 1 | |||
|
3043 | testsbyfailure[key].add(testname) | |||
|
3044 | failuresbytest[testname].add(key) | |||
|
3045 | ||||
|
3046 | # Find test having fewest failures for each failure. | |||
|
3047 | leastfailing = {} | |||
|
3048 | for key, tests in testsbyfailure.items(): | |||
|
3049 | fewesttest = None | |||
|
3050 | fewestcount = 99999999 | |||
|
3051 | for test in sorted(tests): | |||
|
3052 | if len(failuresbytest[test]) < fewestcount: | |||
|
3053 | fewesttest = test | |||
|
3054 | fewestcount = len(failuresbytest[test]) | |||
|
3055 | ||||
|
3056 | leastfailing[key] = (fewestcount, fewesttest) | |||
|
3057 | ||||
|
3058 | # Create a combined counter so we can sort by total occurrences and | |||
|
3059 | # impacted tests. | |||
|
3060 | combined = {} | |||
|
3061 | for key in exceptioncounts: | |||
|
3062 | combined[key] = (exceptioncounts[key], | |||
|
3063 | len(testsbyfailure[key]), | |||
|
3064 | leastfailing[key][0], | |||
|
3065 | leastfailing[key][1]) | |||
|
3066 | ||||
|
3067 | return { | |||
|
3068 | 'exceptioncounts': exceptioncounts, | |||
|
3069 | 'total': sum(exceptioncounts.values()), | |||
|
3070 | 'combined': combined, | |||
|
3071 | 'leastfailing': leastfailing, | |||
|
3072 | 'byfailure': testsbyfailure, | |||
|
3073 | 'bytest': failuresbytest, | |||
|
3074 | } | |||
3031 |
|
3075 | |||
3032 | if __name__ == '__main__': |
|
3076 | if __name__ == '__main__': | |
3033 | runner = TestRunner() |
|
3077 | runner = TestRunner() |
General Comments 0
You need to be logged in to leave comments.
Login now