1# Add an application level test. 2# 3# An application level test consists of a preprocessing step, running 4# the application itself, and a postprocessing step. In addition, file 5# dependencies can be specified and an overall job weight can be 6# specified. The function should be used as follows: 7# 8# add_application_test( 9# <test-name> 10# [SUBTEST <st_num>] 11# [WEIGHT <n>] 12# [TIMEOUT <seconds>] 13# [FILE_DEPENDENCIES file1 [file2 [file3[...]]]] 14# [PREPROCESS COMMAND <command> [EXIT_CODE <exit-code>]] 15# [APPLICATION COMMAND <command> [EXIT_CODE <exit-code>]] 16# [POSTPROCESS COMMAND <command> [EXIT_CODE <exit-code>]] 17# [LABELS [label1 [label2 [...]]]] 18# [UNIQUE_DIRECTORY] 19# [WORKING_DIRECTORY <work-dir>] 20# [NO_TARGET] 21# ) 22# 23# SUBTEST gives a subtest number which changes added test name to 24# test-name:st_num, but runs in directory test-name 25# 26# The WEIGHT argument specifies the number of processes that will be occupied 27# by the test. The TIMEOUT argument specifies how long the test should be 28# allowed to run in seconds. The FILE_DEPENDENCIES argument specifies any input 29# files the application test requires. These files will be copied to the test 30# execution directory at build time. The PREPROCESS, APPLICATION, and 31# POSTPROCESS arguments specify a preprocessing step, how to run the 32# application itself and any post processing steps that are required. Finally, 33# the LABELS argument specifies any labels to attach to the test. 34# 35# The UNIQUE_DIRECTORY toggle will ensure that the test runs in an 36# isolated subdirectory of the current binary directory, named for the 37# test-name. The directory will be created. 38# 39# WORKING_DIRECTORY will run the test in the specified directory, 40# which must exist. 41# 42# If specified, the NO_TARGET toggle will create a custom command for 43# this test, but not a custom target (so the caller can group tests 44# into a single custom target) 45 46include(AddFileCopyTarget) 47include(CMakeParseArguments) 48 49get_filename_component(_add_application_test_dir ${CMAKE_CURRENT_LIST_FILE} PATH) 50 51function(add_application_test _test_name) 52 set(_option_args UNIQUE_DIRECTORY NO_TARGET) 53 set(_one_value_keyword_args 54 WEIGHT 55 TIMEOUT 56 SUBTEST 57 WORKING_DIRECTORY) 58 set(_multi_value_keyword_args 59 FILE_DEPENDENCIES 60 CONFIGURE_FILES 61 PREPROCESS 62 APPLICATION 63 POSTPROCESS 64 LABELS) 65 66 cmake_parse_arguments( 67 _application_test 68 "${_option_args}" 69 "${_one_value_keyword_args}" 70 "${_multi_value_keyword_args}" 71 ${ARGN}) 72 73 # Setup default values for the arguments. 74 if(NOT _application_test_WEIGHT) 75 set(_application_test_WEIGHT 1) 76 endif() 77 if(NOT _application_test_TIMEOUT) 78 set(_application_test_TIMEOUT 0) 79 endif() 80 if(NOT _application_test_WORKING_DIRECTORY) 81 set(_application_test_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 82 endif() 83 84 set(_full_test_name ${_test_name}) 85 if(DEFINED _application_test_SUBTEST) 86 set(_full_test_name "${_test_name}:${_application_test_SUBTEST}") 87 endif() 88 89 # If an isolated subdirectory was requested, create the unique subdirectory 90 # to contain the test's input files. 91 if(_application_test_UNIQUE_DIRECTORY) 92 set(_application_test_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_test_name}") 93 file(MAKE_DIRECTORY "${_application_test_WORKING_DIRECTORY}") 94 endif() 95 96 # Add targets to copy all of the test dependencies to the working 97 # directory at build time. 98 foreach(_file ${_application_test_FILE_DEPENDENCIES}) 99 get_filename_component(_filename ${_file} NAME) 100 101 # Add custom command and optional target 102 if(_application_test_NO_TARGET) 103 add_file_copy_command( 104 ${CMAKE_CURRENT_SOURCE_DIR}/${_file} 105 ${_application_test_WORKING_DIRECTORY}/${_file} 106 ) 107 else() 108 add_file_copy_target( 109 copy_${_full_test_name}_${_filename} 110 ${CMAKE_CURRENT_SOURCE_DIR}/${_file} 111 ${_application_test_WORKING_DIRECTORY}/${_file}) 112 endif() 113 114 endforeach() # file in dependencies 115 116 # Configure any test dependencies to the working directory at configure. 117 foreach(_file ${_application_test_CONFIGURE_FILES}) 118 get_filename_component(_filename ${_file} NAME) 119 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${_file} 120 ${_application_test_WORKING_DIRECTORY}/${_file} @ONLY) 121 endforeach() # file in dependencies 122 123 # Parse each of the PREPROCESS, APPLICATION, POSTPROCESS argument lists. 124 set(_phases PREPROCESS APPLICATION POSTPROCESS) 125 foreach(_phase ${_phases}) 126 cmake_parse_arguments( 127 _application_test_${_phase} 128 "" 129 "EXIT_CODE" 130 "COMMAND" 131 "${_application_test_${_phase}}") 132 if(NOT _application_test_${_phase}_EXIT_CODE) 133 set(_application_test_${_phase}_EXIT_CODE 0) 134 endif() 135 endforeach() 136 137 # Configure the driver script. 138 set(_test_driver_file ${_application_test_WORKING_DIRECTORY}/TEST-${_full_test_name}.cmake) 139 configure_file( 140 ${_add_application_test_dir}/ApplicationTest.cmake.in 141 ${_test_driver_file} 142 @ONLY) 143 144 # Add the test that runs the driver. 145 add_test(NAME ${_full_test_name} 146 WORKING_DIRECTORY "${_application_test_WORKING_DIRECTORY}" 147 COMMAND ${CMAKE_COMMAND} -P ${_test_driver_file}) 148 149 # Set up the test properties. 150 set_tests_properties( 151 ${_full_test_name} 152 PROPERTIES 153 PROCESSORS ${_application_test_WEIGHT} 154 TIMEOUT ${_application_test_TIMEOUT} 155 LABELS "${_application_test_LABELS}") 156 157 158endfunction() 159