206 lines · python
1# -*- coding: utf-8 -*-2# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3# See https://llvm.org/LICENSE.txt for license information.4# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5 6import libear7from . import call_and_report8import unittest9 10import os.path11import string12import glob13 14 15def prepare_cdb(name, target_dir):16 target_file = "build_{0}.json".format(name)17 this_dir, _ = os.path.split(__file__)18 path = os.path.abspath(os.path.join(this_dir, "..", "src"))19 source_dir = os.path.join(path, "compilation_database")20 source_file = os.path.join(source_dir, target_file + ".in")21 target_file = os.path.join(target_dir, "compile_commands.json")22 with open(source_file, "r") as in_handle:23 with open(target_file, "w") as out_handle:24 for line in in_handle:25 temp = string.Template(line)26 out_handle.write(temp.substitute(path=path))27 return target_file28 29 30def run_analyzer(directory, cdb, args):31 cmd = ["analyze-build", "--cdb", cdb, "--output", directory] + args32 return call_and_report(cmd, [])33 34 35class OutputDirectoryTest(unittest.TestCase):36 def test_regular_keeps_report_dir(self):37 with libear.TemporaryDirectory() as tmpdir:38 cdb = prepare_cdb("regular", tmpdir)39 exit_code, reportdir = run_analyzer(tmpdir, cdb, [])40 self.assertTrue(os.path.isdir(reportdir))41 42 def test_clear_deletes_report_dir(self):43 with libear.TemporaryDirectory() as tmpdir:44 cdb = prepare_cdb("clean", tmpdir)45 exit_code, reportdir = run_analyzer(tmpdir, cdb, [])46 self.assertFalse(os.path.isdir(reportdir))47 48 def test_clear_keeps_report_dir_when_asked(self):49 with libear.TemporaryDirectory() as tmpdir:50 cdb = prepare_cdb("clean", tmpdir)51 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--keep-empty"])52 self.assertTrue(os.path.isdir(reportdir))53 54 55class ExitCodeTest(unittest.TestCase):56 def test_regular_does_not_set_exit_code(self):57 with libear.TemporaryDirectory() as tmpdir:58 cdb = prepare_cdb("regular", tmpdir)59 exit_code, __ = run_analyzer(tmpdir, cdb, [])60 self.assertFalse(exit_code)61 62 def test_clear_does_not_set_exit_code(self):63 with libear.TemporaryDirectory() as tmpdir:64 cdb = prepare_cdb("clean", tmpdir)65 exit_code, __ = run_analyzer(tmpdir, cdb, [])66 self.assertFalse(exit_code)67 68 def test_regular_sets_exit_code_if_asked(self):69 with libear.TemporaryDirectory() as tmpdir:70 cdb = prepare_cdb("regular", tmpdir)71 exit_code, __ = run_analyzer(tmpdir, cdb, ["--status-bugs"])72 self.assertTrue(exit_code)73 74 def test_clear_does_not_set_exit_code_if_asked(self):75 with libear.TemporaryDirectory() as tmpdir:76 cdb = prepare_cdb("clean", tmpdir)77 exit_code, __ = run_analyzer(tmpdir, cdb, ["--status-bugs"])78 self.assertFalse(exit_code)79 80 def test_regular_sets_exit_code_if_asked_from_plist(self):81 with libear.TemporaryDirectory() as tmpdir:82 cdb = prepare_cdb("regular", tmpdir)83 exit_code, __ = run_analyzer(tmpdir, cdb, ["--status-bugs", "--plist"])84 self.assertTrue(exit_code)85 86 def test_clear_does_not_set_exit_code_if_asked_from_plist(self):87 with libear.TemporaryDirectory() as tmpdir:88 cdb = prepare_cdb("clean", tmpdir)89 exit_code, __ = run_analyzer(tmpdir, cdb, ["--status-bugs", "--plist"])90 self.assertFalse(exit_code)91 92 93class OutputFormatTest(unittest.TestCase):94 @staticmethod95 def get_html_count(directory):96 return len(glob.glob(os.path.join(directory, "report-*.html")))97 98 @staticmethod99 def get_plist_count(directory):100 return len(glob.glob(os.path.join(directory, "report-*.plist")))101 102 @staticmethod103 def get_sarif_count(directory):104 return len(glob.glob(os.path.join(directory, "result-*.sarif")))105 106 def test_default_only_creates_html_report(self):107 with libear.TemporaryDirectory() as tmpdir:108 cdb = prepare_cdb("regular", tmpdir)109 exit_code, reportdir = run_analyzer(tmpdir, cdb, [])110 self.assertTrue(os.path.exists(os.path.join(reportdir, "index.html")))111 self.assertEqual(self.get_html_count(reportdir), 2)112 self.assertEqual(self.get_plist_count(reportdir), 0)113 self.assertEqual(self.get_sarif_count(reportdir), 0)114 115 def test_plist_and_html_creates_html_and_plist_reports(self):116 with libear.TemporaryDirectory() as tmpdir:117 cdb = prepare_cdb("regular", tmpdir)118 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--plist-html"])119 self.assertTrue(os.path.exists(os.path.join(reportdir, "index.html")))120 self.assertEqual(self.get_html_count(reportdir), 2)121 self.assertEqual(self.get_plist_count(reportdir), 5)122 self.assertEqual(self.get_sarif_count(reportdir), 0)123 124 def test_plist_only_creates_plist_report(self):125 with libear.TemporaryDirectory() as tmpdir:126 cdb = prepare_cdb("regular", tmpdir)127 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--plist"])128 self.assertFalse(os.path.exists(os.path.join(reportdir, "index.html")))129 self.assertEqual(self.get_html_count(reportdir), 0)130 self.assertEqual(self.get_plist_count(reportdir), 5)131 self.assertEqual(self.get_sarif_count(reportdir), 0)132 133 def test_sarif_only_creates_sarif_result(self):134 with libear.TemporaryDirectory() as tmpdir:135 cdb = prepare_cdb("regular", tmpdir)136 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--sarif"])137 self.assertFalse(os.path.exists(os.path.join(reportdir, "index.html")))138 self.assertTrue(139 os.path.exists(os.path.join(reportdir, "results-merged.sarif"))140 )141 self.assertEqual(self.get_html_count(reportdir), 0)142 self.assertEqual(self.get_plist_count(reportdir), 0)143 self.assertEqual(self.get_sarif_count(reportdir), 5)144 145 def test_sarif_and_html_creates_sarif_and_html_reports(self):146 with libear.TemporaryDirectory() as tmpdir:147 cdb = prepare_cdb("regular", tmpdir)148 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--sarif-html"])149 self.assertTrue(os.path.exists(os.path.join(reportdir, "index.html")))150 self.assertTrue(151 os.path.exists(os.path.join(reportdir, "results-merged.sarif"))152 )153 self.assertEqual(self.get_html_count(reportdir), 2)154 self.assertEqual(self.get_plist_count(reportdir), 0)155 self.assertEqual(self.get_sarif_count(reportdir), 5)156 157 158class FailureReportTest(unittest.TestCase):159 def test_broken_creates_failure_reports(self):160 with libear.TemporaryDirectory() as tmpdir:161 cdb = prepare_cdb("broken", tmpdir)162 exit_code, reportdir = run_analyzer(tmpdir, cdb, [])163 self.assertTrue(os.path.isdir(os.path.join(reportdir, "failures")))164 165 def test_broken_does_not_creates_failure_reports(self):166 with libear.TemporaryDirectory() as tmpdir:167 cdb = prepare_cdb("broken", tmpdir)168 exit_code, reportdir = run_analyzer(tmpdir, cdb, ["--no-failure-reports"])169 self.assertFalse(os.path.isdir(os.path.join(reportdir, "failures")))170 171 172class TitleTest(unittest.TestCase):173 def assertTitleEqual(self, directory, expected):174 import re175 176 patterns = [177 re.compile(r"<title>(?P<page>.*)</title>"),178 re.compile(r"<h1>(?P<head>.*)</h1>"),179 ]180 result = dict()181 182 index = os.path.join(directory, "index.html")183 with open(index, "r") as handler:184 for line in handler.readlines():185 for regex in patterns:186 match = regex.match(line.strip())187 if match:188 result.update(match.groupdict())189 break190 self.assertEqual(result["page"], result["head"])191 self.assertEqual(result["page"], expected)192 193 def test_default_title_in_report(self):194 with libear.TemporaryDirectory() as tmpdir:195 cdb = prepare_cdb("broken", tmpdir)196 exit_code, reportdir = run_analyzer(tmpdir, cdb, [])197 self.assertTitleEqual(reportdir, "src - analyzer results")198 199 def test_given_title_in_report(self):200 with libear.TemporaryDirectory() as tmpdir:201 cdb = prepare_cdb("broken", tmpdir)202 exit_code, reportdir = run_analyzer(203 tmpdir, cdb, ["--html-title", "this is the title"]204 )205 self.assertTitleEqual(reportdir, "this is the title")206