xref: /llvm-project/clang/tools/scan-build-py/tests/functional/cases/test_create_cdb.py (revision 4f4bd41f7098af51c3ba2e62cc635e3c45c294d4)
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
6import libear
7from . import make_args, silent_check_call, silent_call, create_empty_file
8import unittest
9
10import os.path
11import json
12
13
14class CompilationDatabaseTest(unittest.TestCase):
15    @staticmethod
16    def run_intercept(tmpdir, args):
17        result = os.path.join(tmpdir, "cdb.json")
18        make = make_args(tmpdir) + args
19        silent_check_call(["intercept-build", "--cdb", result] + make)
20        return result
21
22    @staticmethod
23    def count_entries(filename):
24        with open(filename, "r") as handler:
25            content = json.load(handler)
26            return len(content)
27
28    def test_successful_build(self):
29        with libear.TemporaryDirectory() as tmpdir:
30            result = self.run_intercept(tmpdir, ["build_regular"])
31            self.assertTrue(os.path.isfile(result))
32            self.assertEqual(5, self.count_entries(result))
33
34    def test_successful_build_with_wrapper(self):
35        with libear.TemporaryDirectory() as tmpdir:
36            result = os.path.join(tmpdir, "cdb.json")
37            make = make_args(tmpdir) + ["build_regular"]
38            silent_check_call(
39                ["intercept-build", "--cdb", result, "--override-compiler"] + make
40            )
41            self.assertTrue(os.path.isfile(result))
42            self.assertEqual(5, self.count_entries(result))
43
44    @unittest.skipIf(os.getenv("TRAVIS"), "ubuntu make return -11")
45    def test_successful_build_parallel(self):
46        with libear.TemporaryDirectory() as tmpdir:
47            result = self.run_intercept(tmpdir, ["-j", "4", "build_regular"])
48            self.assertTrue(os.path.isfile(result))
49            self.assertEqual(5, self.count_entries(result))
50
51    @unittest.skipIf(os.getenv("TRAVIS"), "ubuntu env remove clang from path")
52    def test_successful_build_on_empty_env(self):
53        with libear.TemporaryDirectory() as tmpdir:
54            result = os.path.join(tmpdir, "cdb.json")
55            make = make_args(tmpdir) + ["CC=clang", "build_regular"]
56            silent_check_call(["intercept-build", "--cdb", result, "env", "-"] + make)
57            self.assertTrue(os.path.isfile(result))
58            self.assertEqual(5, self.count_entries(result))
59
60    def test_successful_build_all_in_one(self):
61        with libear.TemporaryDirectory() as tmpdir:
62            result = self.run_intercept(tmpdir, ["build_all_in_one"])
63            self.assertTrue(os.path.isfile(result))
64            self.assertEqual(5, self.count_entries(result))
65
66    def test_not_successful_build(self):
67        with libear.TemporaryDirectory() as tmpdir:
68            result = os.path.join(tmpdir, "cdb.json")
69            make = make_args(tmpdir) + ["build_broken"]
70            silent_call(["intercept-build", "--cdb", result] + make)
71            self.assertTrue(os.path.isfile(result))
72            self.assertEqual(2, self.count_entries(result))
73
74
75class ExitCodeTest(unittest.TestCase):
76    @staticmethod
77    def run_intercept(tmpdir, target):
78        result = os.path.join(tmpdir, "cdb.json")
79        make = make_args(tmpdir) + [target]
80        return silent_call(["intercept-build", "--cdb", result] + make)
81
82    def test_successful_build(self):
83        with libear.TemporaryDirectory() as tmpdir:
84            exitcode = self.run_intercept(tmpdir, "build_clean")
85            self.assertFalse(exitcode)
86
87    def test_not_successful_build(self):
88        with libear.TemporaryDirectory() as tmpdir:
89            exitcode = self.run_intercept(tmpdir, "build_broken")
90            self.assertTrue(exitcode)
91
92
93class ResumeFeatureTest(unittest.TestCase):
94    @staticmethod
95    def run_intercept(tmpdir, target, args):
96        result = os.path.join(tmpdir, "cdb.json")
97        make = make_args(tmpdir) + [target]
98        silent_check_call(["intercept-build", "--cdb", result] + args + make)
99        return result
100
101    @staticmethod
102    def count_entries(filename):
103        with open(filename, "r") as handler:
104            content = json.load(handler)
105            return len(content)
106
107    def test_overwrite_existing_cdb(self):
108        with libear.TemporaryDirectory() as tmpdir:
109            result = self.run_intercept(tmpdir, "build_clean", [])
110            self.assertTrue(os.path.isfile(result))
111            result = self.run_intercept(tmpdir, "build_regular", [])
112            self.assertTrue(os.path.isfile(result))
113            self.assertEqual(2, self.count_entries(result))
114
115    def test_append_to_existing_cdb(self):
116        with libear.TemporaryDirectory() as tmpdir:
117            result = self.run_intercept(tmpdir, "build_clean", [])
118            self.assertTrue(os.path.isfile(result))
119            result = self.run_intercept(tmpdir, "build_regular", ["--append"])
120            self.assertTrue(os.path.isfile(result))
121            self.assertEqual(5, self.count_entries(result))
122
123
124class ResultFormattingTest(unittest.TestCase):
125    @staticmethod
126    def run_intercept(tmpdir, command):
127        result = os.path.join(tmpdir, "cdb.json")
128        silent_check_call(["intercept-build", "--cdb", result] + command, cwd=tmpdir)
129        with open(result, "r") as handler:
130            content = json.load(handler)
131            return content
132
133    def assert_creates_number_of_entries(self, command, count):
134        with libear.TemporaryDirectory() as tmpdir:
135            filename = os.path.join(tmpdir, "test.c")
136            create_empty_file(filename)
137            command.append(filename)
138            cmd = ["sh", "-c", " ".join(command)]
139            cdb = self.run_intercept(tmpdir, cmd)
140            self.assertEqual(count, len(cdb))
141
142    def test_filter_preprocessor_only_calls(self):
143        self.assert_creates_number_of_entries(["cc", "-c"], 1)
144        self.assert_creates_number_of_entries(["cc", "-c", "-E"], 0)
145        self.assert_creates_number_of_entries(["cc", "-c", "-M"], 0)
146        self.assert_creates_number_of_entries(["cc", "-c", "-MM"], 0)
147
148    def assert_command_creates_entry(self, command, expected):
149        with libear.TemporaryDirectory() as tmpdir:
150            filename = os.path.join(tmpdir, command[-1])
151            create_empty_file(filename)
152            cmd = ["sh", "-c", " ".join(command)]
153            cdb = self.run_intercept(tmpdir, cmd)
154            self.assertEqual(" ".join(expected), cdb[0]["command"])
155
156    def test_filter_preprocessor_flags(self):
157        self.assert_command_creates_entry(
158            ["cc", "-c", "-MD", "test.c"], ["cc", "-c", "test.c"]
159        )
160        self.assert_command_creates_entry(
161            ["cc", "-c", "-MMD", "test.c"], ["cc", "-c", "test.c"]
162        )
163        self.assert_command_creates_entry(
164            ["cc", "-c", "-MD", "-MF", "test.d", "test.c"], ["cc", "-c", "test.c"]
165        )
166
167    def test_pass_language_flag(self):
168        self.assert_command_creates_entry(
169            ["cc", "-c", "-x", "c", "test.c"], ["cc", "-c", "-x", "c", "test.c"]
170        )
171        self.assert_command_creates_entry(
172            ["cc", "-c", "test.c"], ["cc", "-c", "test.c"]
173        )
174
175    def test_pass_arch_flags(self):
176        self.assert_command_creates_entry(
177            ["clang", "-c", "test.c"], ["cc", "-c", "test.c"]
178        )
179        self.assert_command_creates_entry(
180            ["clang", "-c", "-arch", "i386", "test.c"],
181            ["cc", "-c", "-arch", "i386", "test.c"],
182        )
183        self.assert_command_creates_entry(
184            ["clang", "-c", "-arch", "i386", "-arch", "armv7l", "test.c"],
185            ["cc", "-c", "-arch", "i386", "-arch", "armv7l", "test.c"],
186        )
187