213 lines
8.8 KiB
Python
213 lines
8.8 KiB
Python
# -*- 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
|
|
from . import call_and_report
|
|
import unittest
|
|
|
|
import os.path
|
|
import string
|
|
import glob
|
|
|
|
|
|
def prepare_cdb(name, target_dir):
|
|
target_file = 'build_{0}.json'.format(name)
|
|
this_dir, _ = os.path.split(__file__)
|
|
path = os.path.abspath(os.path.join(this_dir, '..', 'src'))
|
|
source_dir = os.path.join(path, 'compilation_database')
|
|
source_file = os.path.join(source_dir, target_file + '.in')
|
|
target_file = os.path.join(target_dir, 'compile_commands.json')
|
|
with open(source_file, 'r') as in_handle:
|
|
with open(target_file, 'w') as out_handle:
|
|
for line in in_handle:
|
|
temp = string.Template(line)
|
|
out_handle.write(temp.substitute(path=path))
|
|
return target_file
|
|
|
|
|
|
def run_analyzer(directory, cdb, args):
|
|
cmd = ['analyze-build', '--cdb', cdb, '--output', directory] \
|
|
+ args
|
|
return call_and_report(cmd, [])
|
|
|
|
|
|
class OutputDirectoryTest(unittest.TestCase):
|
|
def test_regular_keeps_report_dir(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
|
|
self.assertTrue(os.path.isdir(reportdir))
|
|
|
|
def test_clear_deletes_report_dir(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('clean', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
|
|
self.assertFalse(os.path.isdir(reportdir))
|
|
|
|
def test_clear_keeps_report_dir_when_asked(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('clean', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--keep-empty'])
|
|
self.assertTrue(os.path.isdir(reportdir))
|
|
|
|
|
|
class ExitCodeTest(unittest.TestCase):
|
|
def test_regular_does_not_set_exit_code(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, __ = run_analyzer(tmpdir, cdb, [])
|
|
self.assertFalse(exit_code)
|
|
|
|
def test_clear_does_not_set_exit_code(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('clean', tmpdir)
|
|
exit_code, __ = run_analyzer(tmpdir, cdb, [])
|
|
self.assertFalse(exit_code)
|
|
|
|
def test_regular_sets_exit_code_if_asked(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs'])
|
|
self.assertTrue(exit_code)
|
|
|
|
def test_clear_does_not_set_exit_code_if_asked(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('clean', tmpdir)
|
|
exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs'])
|
|
self.assertFalse(exit_code)
|
|
|
|
def test_regular_sets_exit_code_if_asked_from_plist(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, __ = run_analyzer(
|
|
tmpdir, cdb, ['--status-bugs', '--plist'])
|
|
self.assertTrue(exit_code)
|
|
|
|
def test_clear_does_not_set_exit_code_if_asked_from_plist(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('clean', tmpdir)
|
|
exit_code, __ = run_analyzer(
|
|
tmpdir, cdb, ['--status-bugs', '--plist'])
|
|
self.assertFalse(exit_code)
|
|
|
|
|
|
class OutputFormatTest(unittest.TestCase):
|
|
@staticmethod
|
|
def get_html_count(directory):
|
|
return len(glob.glob(os.path.join(directory, 'report-*.html')))
|
|
|
|
@staticmethod
|
|
def get_plist_count(directory):
|
|
return len(glob.glob(os.path.join(directory, 'report-*.plist')))
|
|
|
|
@staticmethod
|
|
def get_sarif_count(directory):
|
|
return len(glob.glob(os.path.join(directory, 'result-*.sarif')))
|
|
|
|
def test_default_only_creates_html_report(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
|
|
self.assertTrue(
|
|
os.path.exists(os.path.join(reportdir, 'index.html')))
|
|
self.assertEqual(self.get_html_count(reportdir), 2)
|
|
self.assertEqual(self.get_plist_count(reportdir), 0)
|
|
self.assertEqual(self.get_sarif_count(reportdir), 0)
|
|
|
|
def test_plist_and_html_creates_html_and_plist_reports(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist-html'])
|
|
self.assertTrue(
|
|
os.path.exists(os.path.join(reportdir, 'index.html')))
|
|
self.assertEqual(self.get_html_count(reportdir), 2)
|
|
self.assertEqual(self.get_plist_count(reportdir), 5)
|
|
self.assertEqual(self.get_sarif_count(reportdir), 0)
|
|
|
|
def test_plist_only_creates_plist_report(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist'])
|
|
self.assertFalse(
|
|
os.path.exists(os.path.join(reportdir, 'index.html')))
|
|
self.assertEqual(self.get_html_count(reportdir), 0)
|
|
self.assertEqual(self.get_plist_count(reportdir), 5)
|
|
self.assertEqual(self.get_sarif_count(reportdir), 0)
|
|
|
|
def test_sarif_only_creates_sarif_result(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--sarif'])
|
|
self.assertFalse(
|
|
os.path.exists(os.path.join(reportdir, 'index.html')))
|
|
self.assertTrue(
|
|
os.path.exists(os.path.join(reportdir, 'results-merged.sarif')))
|
|
self.assertEqual(self.get_html_count(reportdir), 0)
|
|
self.assertEqual(self.get_plist_count(reportdir), 0)
|
|
self.assertEqual(self.get_sarif_count(reportdir), 5)
|
|
|
|
def test_sarif_and_html_creates_sarif_and_html_reports(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('regular', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--sarif-html'])
|
|
self.assertTrue(
|
|
os.path.exists(os.path.join(reportdir, 'index.html')))
|
|
self.assertTrue(
|
|
os.path.exists(os.path.join(reportdir, 'results-merged.sarif')))
|
|
self.assertEqual(self.get_html_count(reportdir), 2)
|
|
self.assertEqual(self.get_plist_count(reportdir), 0)
|
|
self.assertEqual(self.get_sarif_count(reportdir), 5)
|
|
|
|
|
|
class FailureReportTest(unittest.TestCase):
|
|
def test_broken_creates_failure_reports(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('broken', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
|
|
self.assertTrue(
|
|
os.path.isdir(os.path.join(reportdir, 'failures')))
|
|
|
|
def test_broken_does_not_creates_failure_reports(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('broken', tmpdir)
|
|
exit_code, reportdir = run_analyzer(
|
|
tmpdir, cdb, ['--no-failure-reports'])
|
|
self.assertFalse(
|
|
os.path.isdir(os.path.join(reportdir, 'failures')))
|
|
|
|
|
|
class TitleTest(unittest.TestCase):
|
|
def assertTitleEqual(self, directory, expected):
|
|
import re
|
|
patterns = [
|
|
re.compile(r'<title>(?P<page>.*)</title>'),
|
|
re.compile(r'<h1>(?P<head>.*)</h1>')
|
|
]
|
|
result = dict()
|
|
|
|
index = os.path.join(directory, 'index.html')
|
|
with open(index, 'r') as handler:
|
|
for line in handler.readlines():
|
|
for regex in patterns:
|
|
match = regex.match(line.strip())
|
|
if match:
|
|
result.update(match.groupdict())
|
|
break
|
|
self.assertEqual(result['page'], result['head'])
|
|
self.assertEqual(result['page'], expected)
|
|
|
|
def test_default_title_in_report(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('broken', tmpdir)
|
|
exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
|
|
self.assertTitleEqual(reportdir, 'src - analyzer results')
|
|
|
|
def test_given_title_in_report(self):
|
|
with libear.TemporaryDirectory() as tmpdir:
|
|
cdb = prepare_cdb('broken', tmpdir)
|
|
exit_code, reportdir = run_analyzer(
|
|
tmpdir, cdb, ['--html-title', 'this is the title'])
|
|
self.assertTitleEqual(reportdir, 'this is the title')
|