Home | History | Annotate | Download | only in unit
      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