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