LYTestImpactFramework.cmake 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. #
  2. # Copyright (c) Contributors to the Open 3D Engine Project.
  3. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. #
  5. # SPDX-License-Identifier: Apache-2.0 OR MIT
  6. #
  7. #
  8. # Path to test instrumentation binary
  9. set(LY_TEST_IMPACT_INSTRUMENTATION_BIN "" CACHE PATH "Path to test impact framework instrumentation binary")
  10. # Name of test impact framework console static library target
  11. set(LY_TEST_IMPACT_CONSOLE_STATIC_TARGET "TestImpact.Frontend.Console.Static")
  12. # Name of test impact framework python coverage gem target
  13. set(LY_TEST_IMPACT_PYTHON_COVERAGE_STATIC_TARGET "PythonCoverage.Editor.Static")
  14. # Name of test impact framework console target
  15. set(LY_TEST_IMPACT_CONSOLE_TARGET "TestImpact.Frontend.Console")
  16. # Directory for test impact artifacts and data
  17. set(LY_TEST_IMPACT_WORKING_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/TestImpactFramework")
  18. # Directory for artifacts generated at runtime
  19. set(LY_TEST_IMPACT_TEMP_DIR "${LY_TEST_IMPACT_WORKING_DIR}/$<CONFIG>/Temp")
  20. # Directory for files that persist between runtime runs
  21. set(LY_TEST_IMPACT_PERSISTENT_DIR "${LY_TEST_IMPACT_WORKING_DIR}/$<CONFIG>/Persistent")
  22. # Directory for static artifacts produced as part of the build system generation process
  23. set(LY_TEST_IMPACT_ARTIFACT_DIR "${LY_TEST_IMPACT_WORKING_DIR}/Artifact")
  24. # Directory for source to build target mappings
  25. set(LY_TEST_IMPACT_SOURCE_TARGET_MAPPING_DIR "${LY_TEST_IMPACT_ARTIFACT_DIR}/Mapping")
  26. # Directory for build target dependency/depender graphs
  27. set(LY_TEST_IMPACT_TARGET_DEPENDENCY_DIR "${LY_TEST_IMPACT_ARTIFACT_DIR}/Dependency")
  28. # Main test enumeration file for all test types
  29. set(LY_TEST_IMPACT_TEST_TYPE_FILE "${LY_TEST_IMPACT_ARTIFACT_DIR}/TestType/All.tests")
  30. # Main gem target file for all shared library gems
  31. set(LY_TEST_IMPACT_GEM_TARGET_FILE "${LY_TEST_IMPACT_ARTIFACT_DIR}/BuildType/All.gems")
  32. # Path to the config file for each build configuration
  33. set(LY_TEST_IMPACT_CONFIG_FILE_PATH "${LY_TEST_IMPACT_PERSISTENT_DIR}/tiaf.json")
  34. # Preprocessor directive for the config file path
  35. set(LY_TEST_IMPACT_CONFIG_FILE_PATH_DEFINITION "LY_TEST_IMPACT_DEFAULT_CONFIG_FILE=\"${LY_TEST_IMPACT_CONFIG_FILE_PATH}\"")
  36. #! ly_test_impact_rebase_file_to_repo_root: rebases the relative and/or absolute path to be relative to repo root directory and places the resulting path in quotes.
  37. #
  38. # \arg:INPUT_FILE the file to rebase
  39. # \arg:OUTPUT_FILE the file after rebasing
  40. # \arg:RELATIVE_DIR_ABS the absolute path that the file will be relatively rebased to
  41. function(ly_test_impact_rebase_file_to_repo_root INPUT_FILE OUTPUT_FILE RELATIVE_DIR_ABS)
  42. # Transform the file paths to absolute paths
  43. set(rebased_file ${INPUT_FILE})
  44. if(NOT IS_ABSOLUTE ${rebased_file})
  45. get_filename_component(rebased_file "${rebased_file}"
  46. REALPATH BASE_DIR "${RELATIVE_DIR_ABS}"
  47. )
  48. endif()
  49. # Rebase absolute path to relative path from repo root
  50. file(RELATIVE_PATH rebased_file ${LY_ROOT_FOLDER} ${rebased_file})
  51. set(${OUTPUT_FILE} ${rebased_file} PARENT_SCOPE)
  52. endfunction()
  53. #! ly_test_impact_rebase_files_to_repo_root: rebases the relative and/or absolute paths to be relative to repo root directory and places the resulting paths in quotes.
  54. #
  55. # \arg:INPUT_FILEs the files to rebase
  56. # \arg:OUTPUT_FILEs the files after rebasing
  57. # \arg:RELATIVE_DIR_ABS the absolute path that the files will be relatively rebased to
  58. function(ly_test_impact_rebase_files_to_repo_root INPUT_FILES OUTPUT_FILES RELATIVE_DIR_ABS)
  59. # Rebase all paths in list to repo root
  60. set(rebased_files "")
  61. foreach(in_file IN LISTS INPUT_FILES)
  62. ly_test_impact_rebase_file_to_repo_root(
  63. ${in_file}
  64. out_file
  65. ${RELATIVE_DIR_ABS}
  66. )
  67. list(APPEND rebased_files "\"${out_file}\"")
  68. endforeach()
  69. set(${OUTPUT_FILES} ${rebased_files} PARENT_SCOPE)
  70. endfunction()
  71. #! ly_test_impact_get_test_launch_method: gets the launch method (either standalone or testrunner) for the specified target.
  72. #
  73. # \arg:TARGET_NAME name of the target
  74. # \arg:LAUNCH_METHOD the type string for the specified target
  75. function(ly_test_impact_get_test_launch_method TARGET_NAME LAUNCH_METHOD)
  76. # Get the test impact framework-friendly launch method string
  77. get_target_property(target_type ${TARGET_NAME} TYPE)
  78. if("${target_type}" STREQUAL "SHARED_LIBRARY" OR "${target_type}" STREQUAL "MODULE_LIBRARY")
  79. set(${LAUNCH_METHOD} "test_runner" PARENT_SCOPE)
  80. elseif("${target_type}" STREQUAL "EXECUTABLE")
  81. set(${LAUNCH_METHOD} "stand_alone" PARENT_SCOPE)
  82. else()
  83. message(FATAL_ERROR "Cannot deduce test target launch method for the target ${TARGET_NAME} with type ${target_type}")
  84. endif()
  85. endfunction()
  86. #! ly_test_impact_extract_google_test_name: extracts the google test name from the composite 'namespace::test_name' string
  87. #
  88. # \arg:COMPOSITE_TEST test in the form 'namespace::test'
  89. # \arg:TEST_NAME name of test
  90. function(ly_test_impact_extract_google_test COMPOSITE_TEST TEST_NAMESPACE TEST_NAME)
  91. get_property(test_components GLOBAL PROPERTY LY_ALL_TESTS_${COMPOSITE_TEST}_TEST_NAME)
  92. # Namespace and test are mandatory
  93. string(REPLACE "::" ";" test_components ${test_components})
  94. list(LENGTH test_components num_test_components)
  95. if(num_test_components LESS 2)
  96. message(FATAL_ERROR "The test ${test_components} appears to have been specified without a namespace, i.e.:\ly_add_googletest/benchmark(NAME ${test_components})\nInstead of (perhaps):\ly_add_googletest/benchmark(NAME Gem::${test_components})\nPlease add the missing namespace before proceeding.")
  97. endif()
  98. list(GET test_components 0 test_namespace)
  99. list(GET test_components 1 test_name)
  100. set(${TEST_NAMESPACE} ${test_namespace} PARENT_SCOPE)
  101. set(${TEST_NAME} ${test_name} PARENT_SCOPE)
  102. endfunction()
  103. #! ly_test_impact_extract_python_test_name: extracts the python test name from the composite 'namespace::test_name' string
  104. #
  105. # \arg:COMPOSITE_TEST test in form 'namespace::test' or 'test'
  106. # \arg:TEST_NAME name of test
  107. function(ly_test_impact_extract_python_test COMPOSITE_TEST TEST_NAME)
  108. get_property(test_components GLOBAL PROPERTY LY_ALL_TESTS_${COMPOSITE_TEST}_TEST_NAME)
  109. # namespace is optional, in which case this component will be simply the test name
  110. string(REPLACE "::" ";" test_components ${test_components})
  111. list(LENGTH test_components num_test_components)
  112. if(num_test_components GREATER 1)
  113. list(GET test_components 1 test_name)
  114. else()
  115. set(test_name ${test_components})
  116. endif()
  117. set(${TEST_NAME} ${test_name} PARENT_SCOPE)
  118. endfunction()
  119. #! ly_test_impact_extract_google_test_params: extracts the suites for the given google test.
  120. #
  121. # \arg:COMPOSITE_TEST test in the form 'namespace::test'
  122. # \arg:COMPOSITE_SUITES composite list of suites for this target
  123. # \arg:TEST_NAME name of test
  124. # \arg:TEST_SUITES extracted list of suites for this target in JSON format
  125. function(ly_test_impact_extract_google_test_params COMPOSITE_TEST COMPOSITE_SUITES TEST_NAME TEST_SUITES)
  126. # Namespace and test are mandatory
  127. string(REPLACE "::" ";" test_components ${COMPOSITE_TEST})
  128. list(LENGTH test_components num_test_components)
  129. if(num_test_components LESS 2)
  130. message(FATAL_ERROR "The test ${test_components} appears to have been specified without a namespace, i.e.:\ly_add_googletest/benchmark(NAME ${test_components})\nInstead of (perhaps):\ly_add_googletest/benchmark(NAME Gem::${test_components})\nPlease add the missing namespace before proceeding.")
  131. endif()
  132. list(GET test_components 0 test_namespace)
  133. list(GET test_components 1 test_name)
  134. set(${TEST_NAMESPACE} ${test_namespace} PARENT_SCOPE)
  135. set(${TEST_NAME} ${test_name} PARENT_SCOPE)
  136. set(test_suites "")
  137. foreach(composite_suite ${COMPOSITE_SUITES})
  138. # Command, suite, timeout
  139. string(REPLACE "#" ";" suite_components ${composite_suite})
  140. list(LENGTH suite_components num_suite_components)
  141. if(num_suite_components LESS 3)
  142. message(FATAL_ERROR "The suite components ${composite_suite} are required to be in the following format: command#suite#string.")
  143. endif()
  144. list(GET suite_components 0 test_command)
  145. list(GET suite_components 1 test_suite)
  146. list(GET suite_components 2 test_timeout)
  147. set(suite_params "{ \"suite\": \"${test_suite}\", \"command\": \"${test_command}\", \"timeout\": ${test_timeout} }")
  148. list(APPEND test_suites "${suite_params}")
  149. endforeach()
  150. string(REPLACE ";" ", " test_suites "${test_suites}")
  151. set(${TEST_SUITES} ${test_suites} PARENT_SCOPE)
  152. endfunction()
  153. #! ly_test_impact_extract_python_test_params: extracts the python test name and relative script path parameters.
  154. #
  155. # \arg:COMPOSITE_TEST test in form 'namespace::test' or 'test'
  156. # \arg:COMPOSITE_SUITES composite list of suites for this target
  157. # \arg:TEST_NAME name of test
  158. # \arg:TEST_SUITES extracted list of suites for this target in JSON format
  159. function(ly_test_impact_extract_python_test_params COMPOSITE_TEST COMPOSITE_SUITES TEST_NAME TEST_SUITES)
  160. get_property(script_path GLOBAL PROPERTY LY_ALL_TESTS_${COMPOSITE_TEST}_SCRIPT_PATH)
  161. # namespace is optional, in which case this component will be simply the test name
  162. string(REPLACE "::" ";" test_components ${COMPOSITE_TEST})
  163. list(LENGTH test_components num_test_components)
  164. if(num_test_components GREATER 1)
  165. list(GET test_components 1 test_name)
  166. else()
  167. set(test_name ${test_components})
  168. endif()
  169. set(${TEST_NAME} ${test_name} PARENT_SCOPE)
  170. set(test_suites "")
  171. foreach(composite_suite ${COMPOSITE_SUITES})
  172. # Script path, suite, timeout
  173. string(REPLACE "#" ";" suite_components ${composite_suite})
  174. list(LENGTH suite_components num_suite_components)
  175. if(num_suite_components LESS 3)
  176. message(FATAL_ERROR "The suite components ${composite_suite} are required to be in the following format: script_path#suite#string.")
  177. endif()
  178. list(GET suite_components 0 script_path)
  179. list(GET suite_components 1 test_suite)
  180. list(GET suite_components 2 test_timeout)
  181. # Get python script path relative to repo root
  182. ly_test_impact_rebase_file_to_repo_root(
  183. "${script_path}"
  184. script_path
  185. "${LY_ROOT_FOLDER}"
  186. )
  187. set(suite_params "{ \"suite\": \"${test_suite}\", \"script\": \"${script_path}\", \"timeout\": ${test_timeout} }")
  188. list(APPEND test_suites "${suite_params}")
  189. endforeach()
  190. string(REPLACE ";" ", " test_suites "${test_suites}")
  191. set(${TEST_SUITES} ${test_suites} PARENT_SCOPE)
  192. endfunction()
  193. #! ly_test_impact_write_test_enumeration_file: exports the main test list to file.
  194. #
  195. # \arg:TEST_ENUMERATION_TEMPLATE_FILE path to test enumeration template file
  196. function(ly_test_impact_write_test_enumeration_file TEST_ENUMERATION_TEMPLATE_FILE)
  197. get_property(LY_ALL_TESTS GLOBAL PROPERTY LY_ALL_TESTS)
  198. # Enumerated tests for each type
  199. set(google_tests "")
  200. set(google_benchmarks "")
  201. set(python_tests "")
  202. set(python_editor_tests "")
  203. set(unknown_tests "")
  204. # Walk the test list
  205. foreach(test ${LY_ALL_TESTS})
  206. message(TRACE "Parsing ${test}")
  207. get_property(test_params GLOBAL PROPERTY LY_ALL_TESTS_${test}_PARAMS)
  208. get_property(test_type GLOBAL PROPERTY LY_ALL_TESTS_${test}_TEST_LIBRARY)
  209. if("${test_type}" STREQUAL "pytest")
  210. # Python tests
  211. ly_test_impact_extract_python_test_params(${test} "${test_params}" test_name test_suites)
  212. list(APPEND python_tests " { \"name\": \"${test_name}\", \"suites\": [${test_suites}] }")
  213. elseif("${test_type}" STREQUAL "pytest_editor")
  214. # Python editor tests
  215. ly_test_impact_extract_python_test_params(${test} "${test_params}" test_name test_suites)
  216. list(APPEND python_editor_tests " { \"name\": \"${test_name}\", \"suites\": [${test_suites}] }")
  217. elseif("${test_type}" STREQUAL "googletest")
  218. # Google tests
  219. ly_test_impact_extract_google_test_params(${test} "${test_params}" test_name test_suites)
  220. ly_test_impact_get_test_launch_method(${test} launch_method)
  221. list(APPEND google_tests " { \"name\": \"${test_name}\", \"launch_method\": \"${launch_method}\", \"suites\": [${test_suites}] }")
  222. elseif("${test_type}" STREQUAL "googlebenchmark")
  223. # Google benchmarks
  224. ly_test_impact_extract_google_test_params(${test} "${test_params}" test_name test_suites)
  225. list(APPEND google_benchmarks " { \"name\": \"${test_name}\", \"launch_method\": \"${launch_method}\", \"suites\": [${test_suites}] }")
  226. else()
  227. ly_test_impact_extract_python_test_params(${test} "${test_params}" test_name test_suites)
  228. message("${test_name} is of unknown type (TEST_LIBRARY property is \"${test_type}\")")
  229. list(APPEND unknown_tests " { \"name\": \"${test}\", \"type\": \"${test_type}\" }")
  230. endif()
  231. endforeach()
  232. string(REPLACE ";" ",\n" google_tests "${google_tests}")
  233. string(REPLACE ";" ",\n" google_benchmarks "${google_benchmarks}")
  234. string(REPLACE ";" ",\n" python_editor_tests "${python_editor_tests}")
  235. string(REPLACE ";" ",\n" python_tests "${python_tests}")
  236. string(REPLACE ";" ",\n" unknown_tests "${unknown_tests}")
  237. # Write out the test enumeration file
  238. configure_file(${TEST_ENUMERATION_TEMPLATE_FILE} ${LY_TEST_IMPACT_TEST_TYPE_FILE})
  239. endfunction()
  240. #! ly_test_impact_write_gem_target_enumeration_file: exports the main gem target list to file.
  241. #
  242. # \arg:GEM_TARGET_TEMPLATE_FILE path to source to gem target template file
  243. function(ly_test_impact_write_gem_target_enumeration_file GEM_TARGET_TEMPLATE_FILE)
  244. get_property(LY_ALL_TARGETS GLOBAL PROPERTY LY_ALL_TARGETS)
  245. set(enumerated_gem_targets "")
  246. # Walk the build targets
  247. foreach(aliased_target ${LY_ALL_TARGETS})
  248. unset(target)
  249. ly_de_alias_target(${aliased_target} target)
  250. get_target_property(gem_module ${target} GEM_MODULE)
  251. get_target_property(target_type ${target} TYPE)
  252. if("${gem_module}" STREQUAL "TRUE")
  253. if("${target_type}" STREQUAL "SHARED_LIBRARY" OR "${target_type}" STREQUAL "MODULE_LIBRARY")
  254. list(APPEND enumerated_gem_targets " \"${target}\"")
  255. endif()
  256. endif()
  257. endforeach()
  258. string (REPLACE ";" ",\n" enumerated_gem_targets "${enumerated_gem_targets}")
  259. # Write out source to target mapping file
  260. set(mapping_path "${LY_TEST_IMPACT_GEM_TARGET_FILE}")
  261. configure_file(${GEM_TARGET_TEMPLATE_FILE} ${mapping_path})
  262. endfunction()
  263. #! ly_test_impact_export_source_target_mappings: exports the static source to target mappings to file.
  264. #
  265. # \arg:MAPPING_TEMPLATE_FILE path to source to target template file
  266. function(ly_test_impact_export_source_target_mappings MAPPING_TEMPLATE_FILE)
  267. get_property(LY_ALL_TARGETS GLOBAL PROPERTY LY_ALL_TARGETS)
  268. # Walk the build targets
  269. foreach(aliased_target ${LY_ALL_TARGETS})
  270. unset(target)
  271. ly_de_alias_target(${aliased_target} target)
  272. message(TRACE "Exporting static source file mappings for ${target}")
  273. # Target name and path relative to root
  274. set(target_name ${target})
  275. get_target_property(target_path_abs ${target} SOURCE_DIR)
  276. file(RELATIVE_PATH target_path ${LY_ROOT_FOLDER} ${target_path_abs})
  277. # Output name
  278. get_target_property(target_output_name ${target} OUTPUT_NAME)
  279. if (target_output_name STREQUAL "target_output_name-NOTFOUND")
  280. # No custom output name was specified so use the target name
  281. set(target_output_name "${target}")
  282. endif()
  283. # Autogen source file mappings
  284. get_target_property(autogen_input_files ${target} AUTOGEN_INPUT_FILES)
  285. get_target_property(autogen_output_files ${target} AUTOGEN_OUTPUT_FILES)
  286. if(DEFINED autogen_input_files AND autogen_output_files)
  287. # Rebase input source file paths to repo root
  288. ly_test_impact_rebase_files_to_repo_root(
  289. "${autogen_input_files}"
  290. autogen_input_files
  291. ${target_path_abs}
  292. )
  293. # Rebase output source file paths to repo root
  294. ly_test_impact_rebase_files_to_repo_root(
  295. "${autogen_output_files}"
  296. autogen_output_files
  297. ${target_path_abs}
  298. )
  299. else()
  300. set(autogen_input_files "")
  301. set(autogen_output_files "")
  302. endif()
  303. # Static source file mappings
  304. get_target_property(static_sources ${target} SOURCES)
  305. # Rebase static source files to repo root
  306. ly_test_impact_rebase_files_to_repo_root(
  307. "${static_sources}"
  308. static_sources
  309. ${target_path_abs}
  310. )
  311. # Add the static source file mappings to the contents
  312. string (REPLACE ";" ",\n" autogen_input_files "${autogen_input_files}")
  313. string (REPLACE ";" ",\n" autogen_output_files "${autogen_output_files}")
  314. string (REPLACE ";" ",\n" static_sources "${static_sources}")
  315. # Write out source to target mapping file
  316. set(mapping_path "${LY_TEST_IMPACT_SOURCE_TARGET_MAPPING_DIR}/${target}.target")
  317. configure_file(${MAPPING_TEMPLATE_FILE} ${mapping_path})
  318. endforeach()
  319. endfunction()
  320. #! ly_test_impact_write_config_file: writes out the test impact framework config file using the data derived from the build generation process.
  321. #
  322. # \arg:CONFIG_TEMPLATE_FILE path to the runtime configuration template file
  323. # \arg:BIN_DIR path to repo binary output directory
  324. function(ly_test_impact_write_config_file CONFIG_TEMPLATE_FILE BIN_DIR)
  325. # Platform this config file is being generated for
  326. set(platform ${PAL_PLATFORM_NAME})
  327. # Timestamp this config file was generated at
  328. string(TIMESTAMP timestamp "%Y-%m-%d %H:%M:%S")
  329. # Build configuration this config file is being generated for
  330. set(build_config "$<CONFIG>")
  331. # Instrumentation binary
  332. if(NOT LY_TEST_IMPACT_INSTRUMENTATION_BIN)
  333. # No binary specified is not an error, it just means that the test impact analysis part of the framework is disabled
  334. message("No test impact framework instrumentation binary was specified, test impact analysis framework will fall back to regular test sequences instead")
  335. set(use_tiaf false)
  336. set(instrumentation_bin "")
  337. else()
  338. set(use_tiaf true)
  339. file(TO_CMAKE_PATH ${LY_TEST_IMPACT_INSTRUMENTATION_BIN} instrumentation_bin)
  340. endif()
  341. # Testrunner binary
  342. set(test_runner_bin $<TARGET_FILE:AzTestRunner>)
  343. # Repository root
  344. set(repo_dir ${LY_ROOT_FOLDER})
  345. # Test impact framework output binary dir
  346. set(bin_dir ${BIN_DIR})
  347. # Temp dir
  348. set(temp_dir "${LY_TEST_IMPACT_TEMP_DIR}")
  349. # Active persistent data dir
  350. set(active_dir "${LY_TEST_IMPACT_PERSISTENT_DIR}/active")
  351. # Historic persistent data dir
  352. set(historic_dir "${LY_TEST_IMPACT_PERSISTENT_DIR}/historic")
  353. # Source to target mappings dir
  354. set(source_target_mapping_dir "${LY_TEST_IMPACT_SOURCE_TARGET_MAPPING_DIR}")
  355. # Test type artifact file
  356. set(test_target_type_file "${LY_TEST_IMPACT_TEST_TYPE_FILE}")
  357. # Gem target file
  358. set(gem_target_file "${LY_TEST_IMPACT_GEM_TARGET_FILE}")
  359. # Build dependency artifact dir
  360. set(target_dependency_dir "${LY_TEST_IMPACT_TARGET_DEPENDENCY_DIR}")
  361. # Test impact analysis framework binary
  362. set(tiaf_bin "$<TARGET_FILE:${LY_TEST_IMPACT_CONSOLE_TARGET}>")
  363. # Substitute config file template with above vars
  364. ly_file_read("${CONFIG_TEMPLATE_FILE}" config_file)
  365. string(CONFIGURE ${config_file} config_file)
  366. # Write out entire config contents to a file in the build directory of the test impact framework console target
  367. file(GENERATE
  368. OUTPUT "${LY_TEST_IMPACT_CONFIG_FILE_PATH}"
  369. CONTENT "${config_file}"
  370. )
  371. message(DEBUG "Test impact framework post steps complete")
  372. endfunction()
  373. #! ly_test_impact_post_step: runs the post steps to be executed after all other cmake scripts have been executed.
  374. function(ly_test_impact_post_step)
  375. if(NOT LY_TEST_IMPACT_INSTRUMENTATION_BIN)
  376. return()
  377. endif()
  378. # Directory for binaries built for this profile
  379. set(bin_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>")
  380. # Erase any existing artifact and non-persistent data to avoid getting test impact framework out of sync with current repo state
  381. file(REMOVE_RECURSE "${LY_TEST_IMPACT_TEMP_DIR}")
  382. file(REMOVE_RECURSE "${LY_TEST_IMPACT_ARTIFACT_DIR}")
  383. # Export the soruce to target mapping files
  384. ly_test_impact_export_source_target_mappings(
  385. "cmake/TestImpactFramework/SourceToTargetMapping.in"
  386. )
  387. # Export the enumerated tests
  388. ly_test_impact_write_test_enumeration_file(
  389. "cmake/TestImpactFramework/EnumeratedTests.in"
  390. )
  391. # Export the enumerated gems
  392. ly_test_impact_write_gem_target_enumeration_file(
  393. "cmake/TestImpactFramework/EnumeratedGemTargets.in"
  394. )
  395. # Write out the configuration file
  396. ly_test_impact_write_config_file(
  397. "cmake/TestImpactFramework/ConsoleFrontendConfig.in"
  398. ${bin_dir}
  399. )
  400. # Copy over the graphviz options file for the build dependency graphs
  401. message(DEBUG "Test impact framework config file written")
  402. file(COPY "cmake/TestImpactFramework/CMakeGraphVizOptions.cmake" DESTINATION ${CMAKE_BINARY_DIR})
  403. endfunction()