]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/scan-build-py/tests/unit/test_report.py
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / tools / scan-build-py / tests / unit / test_report.py
1 # -*- coding: utf-8 -*-
2 #                     The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6
7 import libear
8 import libscanbuild.report as sut
9 import unittest
10 import os
11 import os.path
12
13
14 def run_bug_parse(content):
15     with libear.TemporaryDirectory() as tmpdir:
16         file_name = os.path.join(tmpdir, 'test.html')
17         with open(file_name, 'w') as handle:
18             handle.writelines(content)
19         for bug in sut.parse_bug_html(file_name):
20             return bug
21
22
23 def run_crash_parse(content, preproc):
24     with libear.TemporaryDirectory() as tmpdir:
25         file_name = os.path.join(tmpdir, preproc + '.info.txt')
26         with open(file_name, 'w') as handle:
27             handle.writelines(content)
28         return sut.parse_crash(file_name)
29
30
31 class ParseFileTest(unittest.TestCase):
32
33     def test_parse_bug(self):
34         content = [
35             "some header\n",
36             "<!-- BUGDESC Division by zero -->\n",
37             "<!-- BUGTYPE Division by zero -->\n",
38             "<!-- BUGCATEGORY Logic error -->\n",
39             "<!-- BUGFILE xx -->\n",
40             "<!-- BUGLINE 5 -->\n",
41             "<!-- BUGCOLUMN 22 -->\n",
42             "<!-- BUGPATHLENGTH 4 -->\n",
43             "<!-- BUGMETAEND -->\n",
44             "<!-- REPORTHEADER -->\n",
45             "some tails\n"]
46         result = run_bug_parse(content)
47         self.assertEqual(result['bug_category'], 'Logic error')
48         self.assertEqual(result['bug_path_length'], 4)
49         self.assertEqual(result['bug_line'], 5)
50         self.assertEqual(result['bug_description'], 'Division by zero')
51         self.assertEqual(result['bug_type'], 'Division by zero')
52         self.assertEqual(result['bug_file'], 'xx')
53
54     def test_parse_bug_empty(self):
55         content = []
56         result = run_bug_parse(content)
57         self.assertEqual(result['bug_category'], 'Other')
58         self.assertEqual(result['bug_path_length'], 1)
59         self.assertEqual(result['bug_line'], 0)
60
61     def test_parse_crash(self):
62         content = [
63             "/some/path/file.c\n",
64             "Some very serious Error\n",
65             "bla\n",
66             "bla-bla\n"]
67         result = run_crash_parse(content, 'file.i')
68         self.assertEqual(result['source'], content[0].rstrip())
69         self.assertEqual(result['problem'], content[1].rstrip())
70         self.assertEqual(os.path.basename(result['file']),
71                          'file.i')
72         self.assertEqual(os.path.basename(result['info']),
73                          'file.i.info.txt')
74         self.assertEqual(os.path.basename(result['stderr']),
75                          'file.i.stderr.txt')
76
77     def test_parse_real_crash(self):
78         import libscanbuild.runner as sut2
79         import re
80         with libear.TemporaryDirectory() as tmpdir:
81             filename = os.path.join(tmpdir, 'test.c')
82             with open(filename, 'w') as handle:
83                 handle.write('int main() { return 0')
84             # produce failure report
85             opts = {
86                 'clang': 'clang',
87                 'directory': os.getcwd(),
88                 'flags': [],
89                 'file': filename,
90                 'output_dir': tmpdir,
91                 'language': 'c',
92                 'error_type': 'other_error',
93                 'error_output': 'some output',
94                 'exit_code': 13
95             }
96             sut2.report_failure(opts)
97             # find the info file
98             pp_file = None
99             for root, _, files in os.walk(tmpdir):
100                 keys = [os.path.join(root, name) for name in files]
101                 for key in keys:
102                     if re.match(r'^(.*/)+clang(.*)\.i$', key):
103                         pp_file = key
104             self.assertIsNot(pp_file, None)
105             # read the failure report back
106             result = sut.parse_crash(pp_file + '.info.txt')
107             self.assertEqual(result['source'], filename)
108             self.assertEqual(result['problem'], 'Other Error')
109             self.assertEqual(result['file'], pp_file)
110             self.assertEqual(result['info'], pp_file + '.info.txt')
111             self.assertEqual(result['stderr'], pp_file + '.stderr.txt')
112
113
114 class ReportMethodTest(unittest.TestCase):
115
116     def test_chop(self):
117         self.assertEqual('file', sut.chop('/prefix', '/prefix/file'))
118         self.assertEqual('file', sut.chop('/prefix/', '/prefix/file'))
119         self.assertEqual('lib/file', sut.chop('/prefix/', '/prefix/lib/file'))
120         self.assertEqual('/prefix/file', sut.chop('', '/prefix/file'))
121
122     def test_chop_when_cwd(self):
123         self.assertEqual('../src/file', sut.chop('/cwd', '/src/file'))
124         self.assertEqual('../src/file', sut.chop('/prefix/cwd',
125                                                  '/prefix/src/file'))
126
127
128 class GetPrefixFromCompilationDatabaseTest(unittest.TestCase):
129
130     def test_with_different_filenames(self):
131         self.assertEqual(
132             sut.commonprefix(['/tmp/a.c', '/tmp/b.c']), '/tmp')
133
134     def test_with_different_dirnames(self):
135         self.assertEqual(
136             sut.commonprefix(['/tmp/abs/a.c', '/tmp/ack/b.c']), '/tmp')
137
138     def test_no_common_prefix(self):
139         self.assertEqual(
140             sut.commonprefix(['/tmp/abs/a.c', '/usr/ack/b.c']), '/')
141
142     def test_with_single_file(self):
143         self.assertEqual(
144             sut.commonprefix(['/tmp/a.c']), '/tmp')
145
146     def test_empty(self):
147         self.assertEqual(
148             sut.commonprefix([]), '')
149
150 class ReportDirectoryTest(unittest.TestCase):
151
152     # Test that successive report directory names ascend in lexicographic
153     # order. This is required so that report directories from two runs of
154     # scan-build can be easily matched up to compare results.
155     def test_directory_name_comparison(self):
156         with libear.TemporaryDirectory() as tmpdir, \
157              sut.report_directory(tmpdir, False) as report_dir1, \
158              sut.report_directory(tmpdir, False) as report_dir2, \
159              sut.report_directory(tmpdir, False) as report_dir3:
160             self.assertLess(report_dir1, report_dir2)
161             self.assertLess(report_dir2, report_dir3)