test_non_default_target.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. import logging
  4. import shutil
  5. from pathlib import Path
  6. from typing import List, Optional
  7. import pytest
  8. from test_build_system_helpers import EnvDict, IdfPyFunc, file_contains, run_cmake
  9. ESP32C3_TARGET = 'esp32c3'
  10. ESP32C2_TARGET = 'esp32c2'
  11. ESP32S3_TARGET = 'esp32s3'
  12. ESP32S2_TARGET = 'esp32s2'
  13. ESP32_TARGET = 'esp32'
  14. def clean_app(test_app_copy: Path) -> None:
  15. shutil.rmtree(test_app_copy / 'build')
  16. (test_app_copy / 'sdkconfig').unlink()
  17. @pytest.mark.usefixtures('test_app_copy')
  18. def test_target_from_environment_cmake(default_idf_env: EnvDict) -> None:
  19. logging.info('Can override IDF_TARGET from environment')
  20. env = default_idf_env
  21. env.update({'IDF_TARGET': ESP32S2_TARGET})
  22. run_cmake('-G', 'Ninja', '..', env=env)
  23. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  24. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  25. def test_target_from_environment_idf_py(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app_copy: Path) -> None:
  26. def reconfigure_and_check_return_values(errmsg: str, opts: Optional[List[str]] = None) -> None:
  27. opts = opts or []
  28. ret = idf_py(*opts, 'reconfigure', check=False)
  29. assert ret.returncode == 2
  30. assert errmsg in ret.stderr
  31. idf_py('set-target', ESP32S2_TARGET)
  32. default_idf_env.update({'IDF_TARGET': ESP32_TARGET})
  33. cfg_path = (test_app_copy / 'sdkconfig')
  34. logging.info("idf.py fails if IDF_TARGET settings don't match the environment")
  35. reconfigure_and_check_return_values("Project sdkconfig '{}' was generated for target '{}', but environment "
  36. "variable IDF_TARGET is set to '{}'.".format(cfg_path, ESP32S2_TARGET,
  37. ESP32_TARGET))
  38. logging.info("idf.py fails if IDF_TARGET settings in CMakeCache.txt don't match the environment")
  39. (test_app_copy / 'sdkconfig').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
  40. reconfigure_and_check_return_values("Target settings are not consistent: '{}' in the environment, "
  41. "'{}' in CMakeCache.txt.".format(ESP32_TARGET, ESP32S2_TARGET))
  42. logging.info("idf.py fails if IDF_TARGET settings in CMakeCache.txt don't match the sdkconfig")
  43. default_idf_env.pop('IDF_TARGET')
  44. reconfigure_and_check_return_values("Project sdkconfig '{}' was generated for target '{}', but CMakeCache.txt "
  45. "contains '{}'.".format(cfg_path, ESP32_TARGET, ESP32S2_TARGET))
  46. logging.info('idf.py fails if IDF_TARGET is set differently in environment and with -D option')
  47. (test_app_copy / 'sdkconfig').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  48. default_idf_env.update({'IDF_TARGET': ESP32S2_TARGET})
  49. reconfigure_and_check_return_values("Target '{}' specified on command line is not consistent with target '{}' "
  50. 'in the environment.'.format(ESP32_TARGET, ESP32S2_TARGET),
  51. ['-D', 'IDF_TARGET={}'.format(ESP32_TARGET)])
  52. logging.info('idf.py fails if IDF_TARGET is set differently in CMakeCache.txt and with -D option')
  53. default_idf_env.pop('IDF_TARGET')
  54. reconfigure_and_check_return_values("Target '{}' specified on command line is not consistent with "
  55. "target '{}' in CMakeCache.txt.".format(ESP32_TARGET, ESP32S2_TARGET),
  56. ['-D', 'IDF_TARGET={}'.format(ESP32_TARGET)])
  57. def test_target_consistency_cmake(default_idf_env: EnvDict, test_app_copy: Path) -> None:
  58. def reconfigure_and_check_return_values(errmsg: str, opts: Optional[List[str]] = None) -> None:
  59. opts = opts or []
  60. ret = run_cmake(*opts, '-G', 'Ninja', '..', env=default_idf_env, check=False)
  61. assert ret.returncode == 1
  62. assert errmsg in ret.stderr
  63. run_cmake('-G', 'Ninja', '..')
  64. cfg_path = (test_app_copy / 'sdkconfig')
  65. logging.info("cmake fails if IDF_TARGET settings don't match the environment")
  66. default_idf_env.update({'IDF_TARGET': ESP32S2_TARGET})
  67. reconfigure_and_check_return_values(f"IDF_TARGET '{ESP32_TARGET}' in CMake cache does not "
  68. f"match currently selected IDF_TARGET '{ESP32S2_TARGET}'")
  69. logging.info("cmake fails if IDF_TARGET settings don't match the sdkconfig")
  70. default_idf_env.pop('IDF_TARGET')
  71. (test_app_copy / 'sdkconfig').write_text(f'CONFIG_IDF_TARGET="{ESP32S2_TARGET}"')
  72. reconfigure_and_check_return_values(f"Target '{ESP32S2_TARGET}' in sdkconfig '{cfg_path}' does not "
  73. f"match currently selected IDF_TARGET '{ESP32_TARGET}'.")
  74. logging.info("cmake fails if IDF_TOOLCHAIN settings don't match the environment")
  75. (test_app_copy / 'sdkconfig').write_text(f'CONFIG_IDF_TARGET="{ESP32_TARGET}"')
  76. default_idf_env.update({'IDF_TOOLCHAIN': 'clang'})
  77. reconfigure_and_check_return_values("IDF_TOOLCHAIN 'gcc' in CMake cache does not match "
  78. "currently selected IDF_TOOLCHAIN 'clang'")
  79. logging.info("cmake fails if IDF_TARGET settings don't match CMAKE_TOOLCHAIN_FILE")
  80. default_idf_env.pop('IDF_TOOLCHAIN')
  81. reconfigure_and_check_return_values("CMAKE_TOOLCHAIN_FILE 'toolchain-esp32' does not "
  82. f"match currently selected IDF_TARGET '{ESP32S2_TARGET}'",
  83. ['-D', f'IDF_TARGET={ESP32S2_TARGET}',
  84. '-D', 'SDKCONFIG=custom_sdkconfig'])
  85. def test_target_precedence(idf_py: IdfPyFunc, default_idf_env: EnvDict, test_app_copy: Path) -> None:
  86. logging.info('IDF_TARGET takes precedence over the value of CONFIG_IDF_TARGET in sdkconfig.defaults')
  87. (test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  88. default_idf_env.update({'IDF_TARGET': ESP32_TARGET})
  89. idf_py('reconfigure')
  90. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
  91. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32_TARGET.upper()))
  92. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
  93. def test_target_using_D_parameter(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  94. logging.info('Can set target using idf.py -D')
  95. idf_py('-DIDF_TARGET={}'.format(ESP32S2_TARGET), 'reconfigure')
  96. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  97. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  98. logging.info('Can set target using -D as subcommand parameter for idf.py')
  99. clean_app(test_app_copy)
  100. idf_py('reconfigure', '-DIDF_TARGET={}'.format(ESP32S2_TARGET))
  101. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  102. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  103. @pytest.mark.usefixtures('test_app_copy')
  104. def test_target_using_settarget_parameter_alternative_name(idf_py: IdfPyFunc) -> None:
  105. logging.info('idf.py understands alternative target names')
  106. idf_py('set-target', ESP32S2_TARGET.upper())
  107. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  108. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  109. @pytest.mark.usefixtures('test_app_copy')
  110. def test_target_using_settarget_parameter(idf_py: IdfPyFunc, default_idf_env: EnvDict) -> None:
  111. logging.info('Can set target using idf.py set-target')
  112. idf_py('set-target', ESP32S2_TARGET)
  113. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  114. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  115. logging.info('Can guess target from sdkconfig, if CMakeCache does not exist')
  116. idf_py('fullclean')
  117. idf_py('reconfigure')
  118. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  119. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  120. logging.info('Can set target if IDF_TARGET env is set and old sdkconfig exists')
  121. default_idf_env.update({'IDF_TARGET': ESP32_TARGET})
  122. idf_py('set-target', ESP32_TARGET)
  123. default_idf_env.pop('IDF_TARGET')
  124. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
  125. def test_target_using_sdkconfig(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  126. logging.info('Can set the default target using sdkconfig.defaults')
  127. (test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  128. idf_py('reconfigure')
  129. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  130. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET_{}=y'.format(ESP32S2_TARGET.upper()))
  131. def test_target_guessing(idf_py: IdfPyFunc, test_app_copy: Path, default_idf_env: EnvDict) -> None:
  132. """
  133. Tests are performed from the lowest to the highest priority, while
  134. configs, except from the sdkconfig, and parameters of previous tests are
  135. preserved.
  136. """
  137. logging.info('Can guess target from sdkconfig.defaults')
  138. (test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
  139. idf_py('reconfigure')
  140. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32_TARGET))
  141. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32_TARGET))
  142. logging.info('Can guess target from SDKCONFIG_DEFAULTS environment variable')
  143. (test_app_copy / 'sdkconfig1').write_text('NOTHING HERE')
  144. (test_app_copy / 'sdkconfig2').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  145. clean_app(test_app_copy)
  146. default_idf_env.update({'SDKCONFIG_DEFAULTS': 'sdkconfig1;sdkconfig2'})
  147. idf_py('reconfigure')
  148. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  149. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S2_TARGET))
  150. logging.info('Can guess target from SDKCONFIG_DEFAULTS using -D')
  151. (test_app_copy / 'sdkconfig3').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S2_TARGET))
  152. (test_app_copy / 'sdkconfig4').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32S3_TARGET))
  153. clean_app(test_app_copy)
  154. idf_py('-D', 'SDKCONFIG_DEFAULTS=sdkconfig4;sdkconfig3', 'reconfigure')
  155. assert file_contains('sdkconfig', 'CONFIG_IDF_TARGET="{}"'.format(ESP32S3_TARGET))
  156. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32S3_TARGET))
  157. logging.info('Can guess target from custom sdkconfig')
  158. (test_app_copy / 'sdkconfig5').write_text('CONFIG_IDF_TARGET="{}"'.format(ESP32C3_TARGET))
  159. clean_app(test_app_copy)
  160. idf_py('-D', 'SDKCONFIG=sdkconfig5', '-D', 'SDKCONFIG_DEFAULTS=sdkconfig4;sdkconfig3', 'reconfigure')
  161. assert file_contains('sdkconfig5', 'CONFIG_IDF_TARGET="{}"'.format(ESP32C3_TARGET))
  162. assert file_contains('build/CMakeCache.txt', 'IDF_TARGET:STRING={}'.format(ESP32C3_TARGET))