1_generate_function_if_testing_is_disabled("catkin_add_nosetests") 2 3# 4# Add Python nose tests. 5# 6# Nose collects tests from the directory ``dir`` automatically. 7# 8# .. note:: The test can be executed by calling ``nosetests`` 9# directly or using: 10# `` make run_tests_${PROJECT_NAME}_nosetests_${dir}`` 11# (where slashes in the ``dir`` are replaced with periods) 12# 13# :param path: a relative or absolute directory to search for 14# nosetests in or a relative or absolute file containing tests 15# :type path: string 16# :param DEPENDENCIES: the targets which must be built before executing 17# the test 18# :type DEPENDENCIES: list of strings 19# :param TIMEOUT: the timeout for individual tests in seconds 20# (default: 60) 21# :type TIMEOUT: integer 22# :param WORKING_DIRECTORY: the working directory when executing the 23# tests (this option can only be used when the ``path`` argument is a 24# file but not when it is a directory) 25# :type WORKING_DIRECTORY: string 26# 27# @public 28# 29function(catkin_add_nosetests path) 30 _warn_if_skip_testing("catkin_add_nosetests") 31 32 if(NOT NOSETESTS) 33 message(STATUS "skipping nosetests(${path}) in project '${PROJECT_NAME}'") 34 return() 35 endif() 36 37 cmake_parse_arguments(_nose "" "TIMEOUT;WORKING_DIRECTORY" "DEPENDENCIES" ${ARGN}) 38 if(NOT _nose_TIMEOUT) 39 set(_nose_TIMEOUT 60) 40 endif() 41 if(NOT _nose_TIMEOUT GREATER 0) 42 message(FATAL_ERROR "nosetests() TIMEOUT argument must be a valid number of seconds greater than zero") 43 endif() 44 45 # check that the directory exists 46 set(_path_name _path_name-NOTFOUND) 47 if(IS_ABSOLUTE ${path}) 48 set(_path_name ${path}) 49 else() 50 find_file(_path_name ${path} 51 PATHS ${CMAKE_CURRENT_SOURCE_DIR} 52 NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 53 if(NOT _path_name) 54 message(FATAL_ERROR "Can't find nosetests path '${path}'") 55 endif() 56 endif() 57 58 # check if coverage reports are being requested 59 if("$ENV{CATKIN_TEST_COVERAGE}" STREQUAL "1") 60 set(_covarg " --with-coverage") 61 endif() 62 63 # strip PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR prefix from output_file_name 64 set(output_file_name ${path}) 65 _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_SOURCE_DIR}") 66 _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_BINARY_DIR}") 67 if("${output_file_name}" STREQUAL "") 68 set(output_file_name ".") 69 endif() 70 string(REPLACE "/" "." output_file_name ${output_file_name}) 71 string(REPLACE ":" "." output_file_name ${output_file_name}) 72 73 set(output_path ${CATKIN_TEST_RESULTS_DIR}/${PROJECT_NAME}) 74 # make --xunit-file argument an absolute path (https://github.com/nose-devs/nose/issues/779) 75 get_filename_component(output_path "${output_path}" ABSOLUTE) 76 set(cmd "\"${CMAKE_COMMAND}\" -E make_directory ${output_path}") 77 if(IS_DIRECTORY ${_path_name}) 78 set(tests "--where=${_path_name}") 79 else() 80 set(tests "${_path_name}") 81 endif() 82 set(cmd ${cmd} "${NOSETESTS} -P --process-timeout=${_nose_TIMEOUT} ${tests} --with-xunit --xunit-file=${output_path}/nosetests-${output_file_name}.xml${_covarg}") 83 catkin_run_tests_target("nosetests" ${output_file_name} "nosetests-${output_file_name}.xml" COMMAND ${cmd} DEPENDENCIES ${_nose_DEPENDENCIES} WORKING_DIRECTORY ${_nose_WORKING_DIRECTORY}) 84endfunction() 85 86find_program(NOSETESTS NAMES 87 "nosetests${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 88 "nosetests-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 89 "nosetests${PYTHON_VERSION_MAJOR}" 90 "nosetests-${PYTHON_VERSION_MAJOR}" 91 "nosetests") 92if(NOSETESTS) 93 message(STATUS "Using Python nosetests: ${NOSETESTS}") 94else() 95 if("${PYTHON_VERSION_MAJOR}" STREQUAL "3") 96 message(STATUS "nosetests not found, Python tests can not be run (try installing package 'python3-nose')") 97 else() 98 message(STATUS "nosetests not found, Python tests can not be run (try installing package 'python-nose')") 99 endif() 100endif() 101 102function(_strip_path_prefix var value prefix) 103 if("${value}" STREQUAL "${prefix}" OR "${value}" STREQUAL "${prefix}/") 104 set(${var} "" PARENT_SCOPE) 105 else() 106 set(result "${value}") 107 string(LENGTH "${prefix}/" prefix_length) 108 string(LENGTH "${value}" var_length) 109 if(${var_length} GREATER ${prefix_length}) 110 string(SUBSTRING "${value}" 0 ${prefix_length} var_prefix) 111 if("${var_prefix}" STREQUAL "${prefix}/") 112 # passing length -1 does not work for CMake < 2.8.5 113 # http://public.kitware.com/Bug/view.php?id=10740 114 string(LENGTH "${value}" _rest) 115 math(EXPR _rest "${_rest} - ${prefix_length}") 116 string(SUBSTRING "${value}" ${prefix_length} ${_rest} result) 117 endif() 118 endif() 119 set(${var} "${result}" PARENT_SCOPE) 120 endif() 121endfunction() 122