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