test_kconfig.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. import logging
  4. import os
  5. import shutil
  6. import textwrap
  7. from contextlib import contextmanager
  8. from pathlib import Path
  9. from typing import Iterator
  10. import pytest
  11. from test_build_system_helpers import IdfPyFunc, append_to_file, file_contains
  12. @contextmanager
  13. def backup_required_files(test_app_copy: Path) -> Iterator[None]:
  14. idf_path = Path(os.environ['IDF_PATH'])
  15. sdk_rename_backup = (idf_path / 'sdkconfig.rename').read_text()
  16. kconfig_backup = (idf_path / 'Kconfig').read_text()
  17. try:
  18. yield
  19. finally:
  20. (idf_path / 'sdkconfig.rename').write_text(sdk_rename_backup)
  21. (idf_path / 'Kconfig').write_text(kconfig_backup)
  22. shutil.rmtree(test_app_copy / 'build', ignore_errors=True)
  23. if (test_app_copy / 'sdkconfig').exists():
  24. (test_app_copy / 'sdkconfig').unlink()
  25. # For this and the following test function, there are actually two logical
  26. # tests in one test function. It would be better to have every check in a separate
  27. # test case, but that would mean doing idf_copy each time, and copying takes most of the time
  28. @pytest.mark.usefixtures('idf_copy')
  29. def test_kconfig_deprecated_options(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  30. idf_path = Path(os.environ['IDF_PATH'])
  31. with backup_required_files(test_app_copy):
  32. logging.info('Handling deprecated Kconfig options')
  33. (idf_path / 'sdkconfig.rename').write_text('')
  34. idf_py('reconfigure')
  35. append_to_file((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_OLD_OPTION=y')
  36. (idf_path / 'sdkconfig.rename').write_text('CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
  37. append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
  38. menu "test"
  39. config TEST_NEW_OPTION
  40. bool "test"
  41. default "n"
  42. help
  43. TEST_NEW_OPTION description
  44. endmenu
  45. """))
  46. idf_py('reconfigure')
  47. assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION=y',
  48. 'CONFIG_TEST_NEW_OPTION=y']])
  49. assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.h'), x) for x in ['#define CONFIG_TEST_NEW_OPTION 1',
  50. '#define CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION']])
  51. assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.cmake'), x) for x in ['set(CONFIG_TEST_OLD_OPTION "y")',
  52. 'set(CONFIG_TEST_NEW_OPTION "y")']])
  53. logging.info('Handling deprecated Kconfig options in sdkconfig.defaults')
  54. (test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_TEST_OLD_OPTION=7')
  55. (idf_path / 'sdkconfig.rename').write_text('CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
  56. append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
  57. menu "test"
  58. config TEST_NEW_OPTION
  59. int "TEST_NEW_OPTION"
  60. range 0 10
  61. default 5
  62. help
  63. TEST_NEW_OPTION description
  64. endmenu
  65. """))
  66. idf_py('reconfigure')
  67. assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION=7',
  68. 'CONFIG_TEST_NEW_OPTION=7']])
  69. @pytest.mark.usefixtures('idf_copy')
  70. def test_kconfig_multiple_and_target_specific_options(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  71. idf_path = Path(os.environ['IDF_PATH'])
  72. with backup_required_files(test_app_copy):
  73. logging.info('Can have multiple deprecated Kconfig options map to a single new option')
  74. (idf_path / 'sdkconfig.rename').write_text('')
  75. idf_py('reconfigure')
  76. append_to_file((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_NEW_OPTION=y')
  77. append_to_file((idf_path / 'sdkconfig.rename'), '\n'.join(['CONFIG_TEST_OLD_OPTION_1 CONFIG_TEST_NEW_OPTION',
  78. 'CONFIG_TEST_OLD_OPTION_2 CONFIG_TEST_NEW_OPTION']))
  79. append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
  80. menu "test"
  81. config TEST_NEW_OPTION
  82. bool "test"
  83. default "n"
  84. help
  85. TEST_NEW_OPTION description
  86. endmenu
  87. """))
  88. idf_py('reconfigure')
  89. assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_OLD_OPTION_1=y',
  90. 'CONFIG_TEST_OLD_OPTION_2=y']])
  91. assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.h'), x) for x in ['#define CONFIG_TEST_OLD_OPTION_1 CONFIG_TEST_NEW_OPTION',
  92. '#define CONFIG_TEST_OLD_OPTION_2 CONFIG_TEST_NEW_OPTION'
  93. ]])
  94. assert all([file_contains((test_app_copy / 'build' / 'config' / 'sdkconfig.cmake'), x) for x in ['set(CONFIG_TEST_OLD_OPTION_1 "y")',
  95. 'set(CONFIG_TEST_OLD_OPTION_2 "y")']])
  96. logging.info('Can have target specific deprecated Kconfig options')
  97. (test_app_copy / 'sdkconfig').write_text('CONFIG_TEST_OLD_OPTION=y')
  98. append_to_file((idf_path / 'components' / 'esp_system' / 'sdkconfig.rename.esp32s2'), 'CONFIG_TEST_OLD_OPTION CONFIG_TEST_NEW_OPTION')
  99. append_to_file((idf_path / 'Kconfig'), textwrap.dedent("""
  100. menu "test"
  101. config TEST_NEW_OPTION
  102. bool "TEST_NEW_OPTION"
  103. default y
  104. help
  105. TEST_NEW_OPTION description
  106. endmenu
  107. """))
  108. idf_py('set-target', 'esp32')
  109. assert not file_contains((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_OLD_OPTION=y')
  110. assert file_contains((test_app_copy / 'sdkconfig'), 'CONFIG_TEST_NEW_OPTION=y')
  111. (test_app_copy / 'sdkconfig').unlink()
  112. idf_py('set-target', 'esp32s2')
  113. assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_NEW_OPTION=y',
  114. 'CONFIG_TEST_OLD_OPTION=y']])
  115. def test_kconfig_get_version_from_describe(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  116. logging.info('Get the version of app from Kconfig option')
  117. (test_app_copy / 'version.txt').write_text('project_version_from_txt')
  118. (test_app_copy / 'sdkconfig.defaults').write_text('\n'.join(['CONFIG_APP_PROJECT_VER_FROM_CONFIG=y',
  119. 'CONFIG_APP_PROJECT_VER="project_version_from_Kconfig"']))
  120. ret = idf_py('build')
  121. assert 'App "build_test_app" version: project_version_from_Kconfig' in ret.stdout