# -*- 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'(?P<page>.*)'), re.compile(r'

(?P.*)

') ] 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')