blob: 60ec0d855ff337a7dd7a4e167152db06cc5f4ac6 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
import libear
import libscanbuild.report as sut
import unittest
import os
import os.path
def run_bug_parse(content):
with libear.TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, 'test.html')
with open(file_name, 'w') as handle:
handle.writelines(content)
for bug in sut.parse_bug_html(file_name):
return bug
def run_crash_parse(content, preproc):
with libear.TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, preproc + '.info.txt')
with open(file_name, 'w') as handle:
handle.writelines(content)
return sut.parse_crash(file_name)
class ParseFileTest(unittest.TestCase):
def test_parse_bug(self):
content = [
"some header\n",
"<!-- BUGDESC Division by zero -->\n",
"<!-- BUGTYPE Division by zero -->\n",
"<!-- BUGCATEGORY Logic error -->\n",
"<!-- BUGFILE xx -->\n",
"<!-- BUGLINE 5 -->\n",
"<!-- BUGCOLUMN 22 -->\n",
"<!-- BUGPATHLENGTH 4 -->\n",
"<!-- BUGMETAEND -->\n",
"<!-- REPORTHEADER -->\n",
"some tails\n"]
result = run_bug_parse(content)
self.assertEqual(result['bug_category'], 'Logic error')
self.assertEqual(result['bug_path_length'], 4)
self.assertEqual(result['bug_line'], 5)
self.assertEqual(result['bug_description'], 'Division by zero')
self.assertEqual(result['bug_type'], 'Division by zero')
self.assertEqual(result['bug_file'], 'xx')
def test_parse_bug_empty(self):
content = []
result = run_bug_parse(content)
self.assertEqual(result['bug_category'], 'Other')
self.assertEqual(result['bug_path_length'], 1)
self.assertEqual(result['bug_line'], 0)
def test_parse_crash(self):
content = [
"/some/path/file.c\n",
"Some very serious Error\n",
"bla\n",
"bla-bla\n"]
result = run_crash_parse(content, 'file.i')
self.assertEqual(result['source'], content[0].rstrip())
self.assertEqual(result['problem'], content[1].rstrip())
self.assertEqual(os.path.basename(result['file']),
'file.i')
self.assertEqual(os.path.basename(result['info']),
'file.i.info.txt')
self.assertEqual(os.path.basename(result['stderr']),
'file.i.stderr.txt')
def test_parse_real_crash(self):
import libscanbuild.analyze as sut2
import re
with libear.TemporaryDirectory() as tmpdir:
filename = os.path.join(tmpdir, 'test.c')
with open(filename, 'w') as handle:
handle.write('int main() { return 0')
# produce failure report
opts = {
'clang': 'clang',
'directory': os.getcwd(),
'flags': [],
'file': filename,
'output_dir': tmpdir,
'language': 'c',
'error_type': 'other_error',
'error_output': 'some output',
'exit_code': 13
}
sut2.report_failure(opts)
# find the info file
pp_file = None
for root, _, files in os.walk(tmpdir):
keys = [os.path.join(root, name) for name in files]
for key in keys:
if re.match(r'^(.*/)+clang(.*)\.i$', key):
pp_file = key
self.assertIsNot(pp_file, None)
# read the failure report back
result = sut.parse_crash(pp_file + '.info.txt')
self.assertEqual(result['source'], filename)
self.assertEqual(result['problem'], 'Other Error')
self.assertEqual(result['file'], pp_file)
self.assertEqual(result['info'], pp_file + '.info.txt')
self.assertEqual(result['stderr'], pp_file + '.stderr.txt')
class ReportMethodTest(unittest.TestCase):
def test_chop(self):
self.assertEqual('file', sut.chop('/prefix', '/prefix/file'))
self.assertEqual('file', sut.chop('/prefix/', '/prefix/file'))
self.assertEqual('lib/file', sut.chop('/prefix/', '/prefix/lib/file'))
self.assertEqual('/prefix/file', sut.chop('', '/prefix/file'))
def test_chop_when_cwd(self):
self.assertEqual('../src/file', sut.chop('/cwd', '/src/file'))
self.assertEqual('../src/file', sut.chop('/prefix/cwd',
'/prefix/src/file'))
class GetPrefixFromCompilationDatabaseTest(unittest.TestCase):
def test_with_different_filenames(self):
self.assertEqual(
sut.commonprefix(['/tmp/a.c', '/tmp/b.c']), '/tmp')
def test_with_different_dirnames(self):
self.assertEqual(
sut.commonprefix(['/tmp/abs/a.c', '/tmp/ack/b.c']), '/tmp')
def test_no_common_prefix(self):
self.assertEqual(
sut.commonprefix(['/tmp/abs/a.c', '/usr/ack/b.c']), '/')
def test_with_single_file(self):
self.assertEqual(
sut.commonprefix(['/tmp/a.c']), '/tmp')
def test_empty(self):
self.assertEqual(
sut.commonprefix([]), '')