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 7import libear 8import libscanbuild.report as sut 9import unittest 10import os 11import os.path 12 13 14def 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 23def 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 31class 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 114class 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 128class 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