1import pytest 2from unittest.mock import Mock 3from unittest.mock import call 4from checksymbolslib.test_util import assert_db_calls 5import checksymbolslib.makefile as m 6 7 8handle_eval = [ 9 ('generic', 10 'package/foo/foo.mk', 11 5, 12 '$(eval $(generic-package))', 13 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 5)]}), 14 ('ignore trailing whitespace', 15 'package/foo/foo.mk', 16 5, 17 '$(eval $(generic-package)) ', 18 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 5)]}), 19 ('ignore indent', 20 'package/foo/foo.mk', 21 5, 22 '\t$(eval $(generic-package))', 23 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 5)]}), 24 ('rootfs', 25 'fs/foo/foo.mk', 26 5, 27 '$(eval $(rootfs))', 28 {'add_symbol_usage': [ 29 call('BR2_TARGET_ROOTFS_FOO', 'fs/foo/foo.mk', 5), 30 call('BR2_TARGET_ROOTFS_FOO_BZIP2', 'fs/foo/foo.mk', 5), 31 call('BR2_TARGET_ROOTFS_FOO_GZIP', 'fs/foo/foo.mk', 5), 32 call('BR2_TARGET_ROOTFS_FOO_LZ4', 'fs/foo/foo.mk', 5), 33 call('BR2_TARGET_ROOTFS_FOO_LZMA', 'fs/foo/foo.mk', 5), 34 call('BR2_TARGET_ROOTFS_FOO_LZO', 'fs/foo/foo.mk', 5), 35 call('BR2_TARGET_ROOTFS_FOO_XZ', 'fs/foo/foo.mk', 5), 36 call('BR2_TARGET_ROOTFS_FOO_ZSTD', 'fs/foo/foo.mk', 5)]}), 37 ('kernel module', 38 'package/foo/foo.mk', 39 6, 40 '$(eval $(kernel-module))', 41 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 6)]}), 42 ('not an eval for package infra', 43 'docs/manual/manual.mk', 44 10, 45 '$(eval $(call asciidoc-document))', 46 {}), 47 ('linux', 48 'linux/linux.mk', 49 617, 50 '$(eval $(kconfig-package))', 51 {'add_symbol_usage': [call('BR2_LINUX_KERNEL', 'linux/linux.mk', 617)]}), 52 ('virtual toolchain', 53 'toolchain/toolchain-external/toolchain-external.mk', 54 18, 55 '$(eval $(virtual-package))', 56 {'add_symbol_usage': [ 57 call('BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL', 'toolchain/toolchain-external/toolchain-external.mk', 18), 58 call('BR2_PACKAGE_HAS_TOOLCHAIN_EXTERNAL', 'toolchain/toolchain-external/toolchain-external.mk', 18), 59 call('BR2_TOOLCHAIN_EXTERNAL', 'toolchain/toolchain-external/toolchain-external.mk', 18)], 60 'add_symbol_virtual': [call('BR2_TOOLCHAIN_EXTERNAL', 'toolchain/toolchain-external/toolchain-external.mk', 18)]}), 61 ('virtual package', 62 'package/foo/foo.mk', 63 18, 64 '$(eval $(virtual-package))', 65 {'add_symbol_usage': [ 66 call('BR2_PACKAGE_PROVIDES_FOO', 'package/foo/foo.mk', 18), 67 call('BR2_PACKAGE_HAS_FOO', 'package/foo/foo.mk', 18), 68 call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 18)], 69 'add_symbol_virtual': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 18)]}), 70 ('host virtual package', 71 'package/foo/foo.mk', 72 18, 73 '$(eval $(host-virtual-package))', 74 {'add_symbol_usage': [ 75 call('BR2_PACKAGE_PROVIDES_HOST_FOO', 'package/foo/foo.mk', 18), 76 call('BR2_PACKAGE_HAS_HOST_FOO', 'package/foo/foo.mk', 18), 77 call('BR2_PACKAGE_HOST_FOO', 'package/foo/foo.mk', 18)]}), 78 ('host generic package', 79 'package/foo/foo.mk', 80 18, 81 '$(eval $(host-package))', 82 {'add_symbol_usage': [call('BR2_PACKAGE_HOST_FOO', 'package/foo/foo.mk', 18)]}), 83 ('boot package', 84 'boot/foo/foo.mk', 85 18, 86 '$(eval $(generic-package))', 87 {'add_symbol_usage': [call('BR2_TARGET_FOO', 'boot/foo/foo.mk', 18)]}), 88 ('toolchain package', 89 'toolchain/foo/foo.mk', 90 18, 91 '$(eval $(generic-package))', 92 {'add_symbol_usage': [call('BR2_FOO', 'toolchain/foo/foo.mk', 18)]}), 93 ('generic package', 94 'package/foo/foo.mk', 95 18, 96 '$(eval $(generic-package))', 97 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 18)]}), 98 ('cmake package', 99 'package/foo/foo.mk', 100 18, 101 '$(eval $(cmake-package))', 102 {'add_symbol_usage': [call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 18)]}), 103 ] 104 105 106@pytest.mark.parametrize('testname,filename,lineno,line,expected_calls', handle_eval) 107def test_handle_eval(testname, filename, lineno, line, expected_calls): 108 db = Mock() 109 m.handle_eval(db, filename, lineno, line) 110 assert_db_calls(db, expected_calls) 111 112 113handle_definition = [ 114 ('legacy attribution', 115 'Makefile.legacy', 116 9, 117 'BR2_LEGACY_FOO := foo', 118 True, 119 {'add_symbol_legacy_definition': [call('BR2_LEGACY_FOO', 'Makefile.legacy', 9)]}), 120 ('attribution 1', 121 'Makefile', 122 9, 123 'BR2_FOO ?= foo', 124 False, 125 {'add_symbol_definition': [call('BR2_FOO', 'Makefile', 9)]}), 126 ('attribution 2', 127 'Makefile', 128 9, 129 'BR2_FOO = $(BR2_BAR)', 130 False, 131 {'add_symbol_definition': [call('BR2_FOO', 'Makefile', 9)]}), 132 ('attribution 3', 133 'Makefile', 134 9, 135 'BR2_FOO := foo', 136 False, 137 {'add_symbol_definition': [call('BR2_FOO', 'Makefile', 9)]}), 138 ('normal export', 139 'Makefile', 140 90, 141 'export BR2_FOO', 142 False, 143 {'add_symbol_definition': [call('BR2_FOO', 'Makefile', 90)]}), 144 ('legacy export', 145 'Makefile.legacy', 146 90, 147 'export BR2_FOO', 148 True, 149 {'add_symbol_legacy_definition': [call('BR2_FOO', 'Makefile.legacy', 90)]}), 150 ] 151 152 153@pytest.mark.parametrize('testname,filename,lineno,line,legacy,expected_calls', handle_definition) 154def test_handle_definition(testname, filename, lineno, line, legacy, expected_calls): 155 db = Mock() 156 m.handle_definition(db, filename, lineno, line, legacy) 157 assert_db_calls(db, expected_calls) 158 159 160handle_usage = [ 161 ('legacy', 162 'Makefile.legacy', 163 8, 164 'ifeq ($(BR2_LEGACY),y)', 165 True, 166 {'add_symbol_usage_in_legacy': [call('BR2_LEGACY', 'Makefile.legacy', 8)]}), 167 ('attribution', 168 'Makefile', 169 9, 170 'BR2_FOO = $(BR2_BAR)', 171 False, 172 {'add_symbol_usage': [call('BR2_BAR', 'Makefile', 9)]}), 173 ('host virtual package', 174 'package/foo/foo.mk', 175 18, 176 '$(eval $(host-virtual-package))', 177 False, 178 {'add_symbol_usage': [ 179 call('BR2_PACKAGE_PROVIDES_HOST_FOO', 'package/foo/foo.mk', 18), 180 call('BR2_PACKAGE_HAS_HOST_FOO', 'package/foo/foo.mk', 18), 181 call('BR2_PACKAGE_HOST_FOO', 'package/foo/foo.mk', 18)]}), 182 ] 183 184 185@pytest.mark.parametrize('testname,filename,lineno,line,legacy,expected_calls', handle_usage) 186def test_handle_usage(testname, filename, lineno, line, legacy, expected_calls): 187 db = Mock() 188 m.handle_usage(db, filename, lineno, line, legacy) 189 assert_db_calls(db, expected_calls) 190 191 192populate_db = [ 193 ('legacy', 194 'Makefile.legacy', 195 [[8, 'ifeq ($(BR2_LEGACY),y)'], 196 [9, 'BR2_LEGACY_FOO := foo'], 197 [34, 'ifneq ($(BUILDROOT_CONFIG),$(BR2_CONFIG))']], 198 {'add_symbol_usage_in_legacy': [ 199 call('BR2_LEGACY', 'Makefile.legacy', 8), 200 call('BR2_CONFIG', 'Makefile.legacy', 34)], 201 'add_symbol_legacy_definition': [call('BR2_LEGACY_FOO', 'Makefile.legacy', 9)]}), 202 ('attribution', 203 'Makefile', 204 [[9, 'BR2_FOO = $(BR2_BAR)']], 205 {'add_symbol_definition': [call('BR2_FOO', 'Makefile', 9)], 206 'add_symbol_usage': [call('BR2_BAR', 'Makefile', 9)]}), 207 ('legacy attribution', 208 'Makefile.legacy', 209 [[9, 'BR2_FOO = $(BR2_BAR)']], 210 {'add_symbol_legacy_definition': [call('BR2_FOO', 'Makefile.legacy', 9)], 211 'add_symbol_usage_in_legacy': [call('BR2_BAR', 'Makefile.legacy', 9)]}), 212 ('generic', 213 'package/foo/foo.mk', 214 [[3, 'ifeq ($(BR2_PACKAGE_FOO_BAR):$(BR2_BAR),y:)'], 215 [4, 'export BR2_PACKAGE_FOO_BAZ'], 216 [5, '$(eval $(generic-package))']], 217 {'add_symbol_usage': [ 218 call('BR2_PACKAGE_FOO_BAR', 'package/foo/foo.mk', 3), 219 call('BR2_BAR', 'package/foo/foo.mk', 3), 220 call('BR2_PACKAGE_FOO', 'package/foo/foo.mk', 5)], 221 'add_symbol_definition': [call('BR2_PACKAGE_FOO_BAZ', 'package/foo/foo.mk', 4)]}), 222 ('rootfs', 223 'fs/foo/foo.mk', 224 [[4, 'ifeq ($(BR2_TARGET_ROOTFS_FOO_LZ4),y)'], 225 [5, '$(eval $(rootfs))']], 226 {'add_symbol_usage': [ 227 call('BR2_TARGET_ROOTFS_FOO', 'fs/foo/foo.mk', 5), 228 call('BR2_TARGET_ROOTFS_FOO_BZIP2', 'fs/foo/foo.mk', 5), 229 call('BR2_TARGET_ROOTFS_FOO_GZIP', 'fs/foo/foo.mk', 5), 230 call('BR2_TARGET_ROOTFS_FOO_LZ4', 'fs/foo/foo.mk', 4), 231 call('BR2_TARGET_ROOTFS_FOO_LZ4', 'fs/foo/foo.mk', 5), 232 call('BR2_TARGET_ROOTFS_FOO_LZMA', 'fs/foo/foo.mk', 5), 233 call('BR2_TARGET_ROOTFS_FOO_LZO', 'fs/foo/foo.mk', 5), 234 call('BR2_TARGET_ROOTFS_FOO_XZ', 'fs/foo/foo.mk', 5), 235 call('BR2_TARGET_ROOTFS_FOO_ZSTD', 'fs/foo/foo.mk', 5)]}), 236 ] 237 238 239@pytest.mark.parametrize('testname,filename,file_content,expected_calls', populate_db) 240def test_populate_db(testname, filename, file_content, expected_calls): 241 db = Mock() 242 m.populate_db(db, filename, file_content) 243 assert_db_calls(db, expected_calls) 244 245 246check_filename = [ 247 ('arch/arch.mk.riscv', 248 'arch/arch.mk.riscv', 249 True), 250 ('fs/cramfs/cramfs.mk', 251 'fs/cramfs/cramfs.mk', 252 True), 253 ('linux/linux-ext-fbtft.mk', 254 'linux/linux-ext-fbtft.mk', 255 True), 256 ('package/ace/ace.mk', 257 'package/ace/ace.mk', 258 True), 259 ('package/linux-tools/linux-tool-hv.mk.in', 260 'package/linux-tools/linux-tool-hv.mk.in', 261 True), 262 ('package/pkg-generic.mk', 263 'package/pkg-generic.mk', 264 True), 265 ('package/x11r7/xlib_libXt/xlib_libXt.mk', 266 'package/x11r7/xlib_libXt/xlib_libXt.mk', 267 True), 268 ('support/dependencies/check-host-make.mk', 269 'support/dependencies/check-host-make.mk', 270 True), 271 ('toolchain/toolchain-external/toolchain-external-arm-aarch64-be/toolchain-external-arm-aarch64-be.mk', 272 'toolchain/toolchain-external/toolchain-external-arm-aarch64-be/toolchain-external-arm-aarch64-be.mk', 273 True), 274 ('Makefile.legacy', 275 'Makefile.legacy', 276 True), 277 ('boot/common.mk', 278 'boot/common.mk', 279 True), 280 ('fs/common.mk', 281 'fs/common.mk', 282 True), 283 ('Makefile', 284 'Makefile', 285 True), 286 ('package/Makefile.in', 287 'package/Makefile.in', 288 True), 289 ('Config.in', 290 'Config.in', 291 False), 292 ('package/foo/0001-Makefile.patch', 293 'package/foo/0001-Makefile.patch', 294 False), 295 ] 296 297 298@pytest.mark.parametrize('testname,filename,expected', check_filename) 299def test_check_filename(testname, filename, expected): 300 symbols = m.check_filename(filename) 301 assert symbols == expected 302