1 # -*- coding: utf-8 -*-
2 # The LLVM Compiler Infrastructure
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
8 import libscanbuild.report as sut
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):
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)
31 class ParseFileTest(unittest.TestCase):
33 def test_parse_bug(self):
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",
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')
54 def test_parse_bug_empty(self):
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)
61 def test_parse_crash(self):
63 "/some/path/file.c\n",
64 "Some very serious Error\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']),
72 self.assertEqual(os.path.basename(result['info']),
74 self.assertEqual(os.path.basename(result['stderr']),
77 def test_parse_real_crash(self):
78 import libscanbuild.runner as sut2
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
87 'directory': os.getcwd(),
92 'error_type': 'other_error',
93 'error_output': 'some output',
96 sut2.report_failure(opts)
99 for root, _, files in os.walk(tmpdir):
100 keys = [os.path.join(root, name) for name in files]
102 if re.match(r'^(.*/)+clang(.*)\.i$', 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')
114 class ReportMethodTest(unittest.TestCase):
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'))
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',
128 class GetPrefixFromCompilationDatabaseTest(unittest.TestCase):
130 def test_with_different_filenames(self):
132 sut.commonprefix(['/tmp/a.c', '/tmp/b.c']), '/tmp')
134 def test_with_different_dirnames(self):
136 sut.commonprefix(['/tmp/abs/a.c', '/tmp/ack/b.c']), '/tmp')
138 def test_no_common_prefix(self):
140 sut.commonprefix(['/tmp/abs/a.c', '/usr/ack/b.c']), '/')
142 def test_with_single_file(self):
144 sut.commonprefix(['/tmp/a.c']), '/tmp')
146 def test_empty(self):
148 sut.commonprefix([]), '')
150 class ReportDirectoryTest(unittest.TestCase):
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)