test_makefile.py 10 KB

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