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-exception |
5 | |
6 | import libear |
7 | from . import call_and_report |
8 | import unittest |
9 | |
10 | import os.path |
11 | import string |
12 | import glob |
13 | |
14 | |
15 | def prepare_cdb(name, target_dir): |
16 | target_file = 'build_{0}.json'.format(name) |
17 | this_dir, _ = os.path.split(__file__) |
18 | path = os.path.normpath(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_file |
28 | |
29 | |
30 | def run_analyzer(directory, cdb, args): |
31 | cmd = ['analyze-build', '--cdb', cdb, '--output', directory] \ |
32 | + args |
33 | return call_and_report(cmd, []) |
34 | |
35 | |
36 | class OutputDirectoryTest(unittest.TestCase): |
37 | def test_regular_keeps_report_dir(self): |
38 | with libear.TemporaryDirectory() as tmpdir: |
39 | cdb = prepare_cdb('regular', tmpdir) |
40 | exit_code, reportdir = run_analyzer(tmpdir, cdb, []) |
41 | self.assertTrue(os.path.isdir(reportdir)) |
42 | |
43 | def test_clear_deletes_report_dir(self): |
44 | with libear.TemporaryDirectory() as tmpdir: |
45 | cdb = prepare_cdb('clean', tmpdir) |
46 | exit_code, reportdir = run_analyzer(tmpdir, cdb, []) |
47 | self.assertFalse(os.path.isdir(reportdir)) |
48 | |
49 | def test_clear_keeps_report_dir_when_asked(self): |
50 | with libear.TemporaryDirectory() as tmpdir: |
51 | cdb = prepare_cdb('clean', tmpdir) |
52 | exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--keep-empty']) |
53 | self.assertTrue(os.path.isdir(reportdir)) |
54 | |
55 | |
56 | class ExitCodeTest(unittest.TestCase): |
57 | def test_regular_does_not_set_exit_code(self): |
58 | with libear.TemporaryDirectory() as tmpdir: |
59 | cdb = prepare_cdb('regular', tmpdir) |
60 | exit_code, __ = run_analyzer(tmpdir, cdb, []) |
61 | self.assertFalse(exit_code) |
62 | |
63 | def test_clear_does_not_set_exit_code(self): |
64 | with libear.TemporaryDirectory() as tmpdir: |
65 | cdb = prepare_cdb('clean', tmpdir) |
66 | exit_code, __ = run_analyzer(tmpdir, cdb, []) |
67 | self.assertFalse(exit_code) |
68 | |
69 | def test_regular_sets_exit_code_if_asked(self): |
70 | with libear.TemporaryDirectory() as tmpdir: |
71 | cdb = prepare_cdb('regular', tmpdir) |
72 | exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs']) |
73 | self.assertTrue(exit_code) |
74 | |
75 | def test_clear_does_not_set_exit_code_if_asked(self): |
76 | with libear.TemporaryDirectory() as tmpdir: |
77 | cdb = prepare_cdb('clean', tmpdir) |
78 | exit_code, __ = run_analyzer(tmpdir, cdb, ['--status-bugs']) |
79 | self.assertFalse(exit_code) |
80 | |
81 | def test_regular_sets_exit_code_if_asked_from_plist(self): |
82 | with libear.TemporaryDirectory() as tmpdir: |
83 | cdb = prepare_cdb('regular', tmpdir) |
84 | exit_code, __ = run_analyzer( |
85 | tmpdir, cdb, ['--status-bugs', '--plist']) |
86 | self.assertTrue(exit_code) |
87 | |
88 | def test_clear_does_not_set_exit_code_if_asked_from_plist(self): |
89 | with libear.TemporaryDirectory() as tmpdir: |
90 | cdb = prepare_cdb('clean', tmpdir) |
91 | exit_code, __ = run_analyzer( |
92 | tmpdir, cdb, ['--status-bugs', '--plist']) |
93 | self.assertFalse(exit_code) |
94 | |
95 | |
96 | class OutputFormatTest(unittest.TestCase): |
97 | @staticmethod |
98 | def get_html_count(directory): |
99 | return len(glob.glob(os.path.join(directory, 'report-*.html'))) |
100 | |
101 | @staticmethod |
102 | def get_plist_count(directory): |
103 | return len(glob.glob(os.path.join(directory, 'report-*.plist'))) |
104 | |
105 | def test_default_creates_html_report(self): |
106 | with libear.TemporaryDirectory() as tmpdir: |
107 | cdb = prepare_cdb('regular', tmpdir) |
108 | exit_code, reportdir = run_analyzer(tmpdir, cdb, []) |
109 | self.assertTrue( |
110 | 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 | |
114 | def test_plist_and_html_creates_html_report(self): |
115 | with libear.TemporaryDirectory() as tmpdir: |
116 | cdb = prepare_cdb('regular', tmpdir) |
117 | exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist-html']) |
118 | self.assertTrue( |
119 | 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 | |
123 | def test_plist_does_not_creates_html_report(self): |
124 | with libear.TemporaryDirectory() as tmpdir: |
125 | cdb = prepare_cdb('regular', tmpdir) |
126 | exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist']) |
127 | self.assertFalse( |
128 | 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 | |
132 | |
133 | class FailureReportTest(unittest.TestCase): |
134 | def test_broken_creates_failure_reports(self): |
135 | with libear.TemporaryDirectory() as tmpdir: |
136 | cdb = prepare_cdb('broken', tmpdir) |
137 | exit_code, reportdir = run_analyzer(tmpdir, cdb, []) |
138 | self.assertTrue( |
139 | os.path.isdir(os.path.join(reportdir, 'failures'))) |
140 | |
141 | def test_broken_does_not_creates_failure_reports(self): |
142 | with libear.TemporaryDirectory() as tmpdir: |
143 | cdb = prepare_cdb('broken', tmpdir) |
144 | exit_code, reportdir = run_analyzer( |
145 | tmpdir, cdb, ['--no-failure-reports']) |
146 | self.assertFalse( |
147 | os.path.isdir(os.path.join(reportdir, 'failures'))) |
148 | |
149 | |
150 | class TitleTest(unittest.TestCase): |
151 | def assertTitleEqual(self, directory, expected): |
152 | import re |
153 | patterns = [ |
154 | re.compile(r'<title>(?P<page>.*)</title>'), |
155 | re.compile(r'<h1>(?P<head>.*)</h1>') |
156 | ] |
157 | result = dict() |
158 | |
159 | index = os.path.join(directory, 'index.html') |
160 | with open(index, 'r') as handler: |
161 | for line in handler.readlines(): |
162 | for regex in patterns: |
163 | match = regex.match(line.strip()) |
164 | if match: |
165 | result.update(match.groupdict()) |
166 | break |
167 | self.assertEqual(result['page'], result['head']) |
168 | self.assertEqual(result['page'], expected) |
169 | |
170 | def test_default_title_in_report(self): |
171 | with libear.TemporaryDirectory() as tmpdir: |
172 | cdb = prepare_cdb('broken', tmpdir) |
173 | exit_code, reportdir = run_analyzer(tmpdir, cdb, []) |
174 | self.assertTitleEqual(reportdir, 'src - analyzer results') |
175 | |
176 | def test_given_title_in_report(self): |
177 | with libear.TemporaryDirectory() as tmpdir: |
178 | cdb = prepare_cdb('broken', tmpdir) |
179 | exit_code, reportdir = run_analyzer( |
180 | tmpdir, cdb, ['--html-title', 'this is the title']) |
181 | self.assertTitleEqual(reportdir, 'this is the title') |
182 | |