diff --git a/scripts/ci/extends/test-artifacts.yml b/scripts/ci/extends/test-artifacts.yml index 27700422e2aef0826e690b58f723cf4a757e912b..cf865c4e6ec9258d765b671600c625ac9d3cdf3e 100644 --- a/scripts/ci/extends/test-artifacts.yml +++ b/scripts/ci/extends/test-artifacts.yml @@ -2,7 +2,7 @@ artifacts: when: always paths: - - build/*/logs/*.txt + - build/*/logs - build/*/Tests/ctest-junit.xml - build/*/Tests/testrunner.xml - build/*/make.txt diff --git a/scripts/cmake/PythonSetup.cmake b/scripts/cmake/PythonSetup.cmake index 26efb4067e046a99fdc620429e3f3fd23b4f678a..329e35ce5463f91cc297ba44aa90dbadba9cc5f2 100644 --- a/scripts/cmake/PythonSetup.cmake +++ b/scripts/cmake/PythonSetup.cmake @@ -210,9 +210,7 @@ function(setup_venv_dependent_ctests) EXECUTABLE ogs EXECUTABLE_ARGS ${ht_invalid_prj_file} RUNTIME 1 - ) - set_tests_properties( - ogs-HT_${ht_invalid_prj_file_short} PROPERTIES WILL_FAIL TRUE + PROPERTIES WILL_FAIL TRUE ) endforeach() endif() diff --git a/scripts/cmake/test/AddTest.cmake b/scripts/cmake/test/AddTest.cmake index 6e84772c2634c7b9e27e8408e5d7fb6dbf26a56a..9d35517e9e2df5e9713f257d2269ced6895ceb53 100644 --- a/scripts/cmake/test/AddTest.cmake +++ b/scripts/cmake/test/AddTest.cmake @@ -346,6 +346,9 @@ macro(_add_test TEST_NAME) ) endif() + isTestCommandExpectedToSucceed(${TEST_NAME} ${AddTest_PROPERTIES}) + message(DEBUG "Is test '${TEST_NAME}' expected to succeed? → ${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}") + add_test( NAME ${TEST_NAME} COMMAND @@ -355,8 +358,10 @@ macro(_add_test TEST_NAME) -DBINARY_PATH=${_binary_path} -DWRAPPER_COMMAND=${WRAPPER_COMMAND} "-DWRAPPER_ARGS=${AddTest_WRAPPER_ARGS}" -DWORKING_DIRECTORY=${AddTest_WORKING_DIRECTORY} - -DLOG_FILE=${PROJECT_BINARY_DIR}/logs/${TEST_NAME}.txt -P - ${PROJECT_SOURCE_DIR}/scripts/cmake/test/AddTestWrapper.cmake + "-DLOG_ROOT=${PROJECT_BINARY_DIR}/logs" + "-DLOG_FILE_BASENAME=${TEST_NAME}.txt" + "-DTEST_COMMAND_IS_EXPECTED_TO_SUCCEED=${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}" + -P ${PROJECT_SOURCE_DIR}/scripts/cmake/test/AddTestWrapper.cmake ) if(DEFINED AddTest_DEPENDS) @@ -607,3 +612,47 @@ Use six arguments version of AddTest with absolute and relative tolerances" ${AddTest_DISABLED} LABELS "tester;${labels}" ) endmacro() + +# Checks if a test is expected to succeed based on the properties WILL_FAIL, +# PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION. +# The function expects the test name (used only for debugging purposes) and the +# test properties as arguments. +# The test does not need to exist, yet. This function does not query any test +# case, but only uses the passed list of properties +function(isTestCommandExpectedToSucceed TEST_NAME) + set(options WILL_FAIL) + set(oneValueArgs PASS_REGULAR_EXPRESSION FAIL_REGULAR_EXPRESSION) + set(multiValueArgs) + cmake_parse_arguments(TEST_FAILURE "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN}) + + message(DEBUG "failure properties for test ${TEST_NAME}:") + list(APPEND CMAKE_MESSAGE_INDENT " ") + message(DEBUG "WILL_FAIL: ${TEST_FAILURE_WILL_FAIL}") + message(DEBUG "PASS_RE: ${TEST_FAILURE_PASS_REGULAR_EXPRESSION}") + message(DEBUG "FAIL_RE: ${TEST_FAILURE_FAIL_REGULAR_EXPRESSION}") + list(POP_BACK CMAKE_MESSAGE_INDENT) + + if (${TEST_FAILURE_WILL_FAIL}) + if (DEFINED TEST_FAILURE_PASS_REGULAR_EXPRESSION) + # Note: if the test property PASS_REGULAR_EXPRESSION is set, the + # process return code will be ignored, see https://cmake.org/cmake/help/latest/prop_test/PASS_REGULAR_EXPRESSION.html + message(SEND_ERROR "Error in test '${TEST_NAME}': Please do not use both WILL_FAIL and PASS_REGULAR_EXPRESSION in the same test. The logic will be unclear, then.") + endif() + if (DEFINED TEST_FAILURE_FAIL_REGULAR_EXPRESSION) + message(SEND_ERROR "Error in test '${TEST_NAME}': Please do not use both WILL_FAIL and FAIL_REGULAR_EXPRESSION in the same test. The logic will be unclear, then.") + endif() + + set(TEST_COMMAND_IS_EXPECTED_TO_SUCCEED false) + elseif(DEFINED TEST_FAILURE_PASS_REGULAR_EXPRESSION) + if (DEFINED TEST_FAILURE_FAIL_REGULAR_EXPRESSION) + message(SEND_ERROR "Error in test '${TEST_NAME}': Please do not use both PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION in the same test. The logic will be unclear, then.") + endif() + + set(TEST_COMMAND_IS_EXPECTED_TO_SUCCEED false) + else() + set(TEST_COMMAND_IS_EXPECTED_TO_SUCCEED true) + endif() + + set(TEST_COMMAND_IS_EXPECTED_TO_SUCCEED "${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}" PARENT_SCOPE) +endfunction() diff --git a/scripts/cmake/test/AddTestWrapper.cmake b/scripts/cmake/test/AddTestWrapper.cmake index c9a3116a010609dcfdf6dfe05a19f43445b4676b..2249f7b7e81f56f483bb6aed35c6a10dfe1822d1 100644 --- a/scripts/cmake/test/AddTestWrapper.cmake +++ b/scripts/cmake/test/AddTestWrapper.cmake @@ -1,4 +1,4 @@ -# IMPORTANT: multiple arguments in one variables have to be in list notation (;) +# IMPORTANT: multiple arguments in a single variable have to be in list notation (;) # and have to be quoted when passed # "-DEXECUTABLE_ARGS=${AddTest_EXECUTABLE_ARGS}" execute_process( @@ -12,9 +12,43 @@ execute_process( COMMAND_ECHO STDOUT ) -if(EXIT_CODE STREQUAL "0" AND NOT DEFINED ENV{CI}) - file(WRITE ${LOG_FILE} "${LOG}") -elseif(NOT EXIT_CODE STREQUAL "0") - file(WRITE ${LOG_FILE} "${LOG}") +set(SAVE_LOG true) +set(TEST_LOG_DIR "${LOG_ROOT}") + +if (TEST_COMMAND_IS_EXPECTED_TO_SUCCEED) + if (EXIT_CODE STREQUAL "0") + # expected: success, actual: success + if (DEFINED ENV{CI}) + set(SAVE_LOG false) + endif() + else() + # expected: success, actual: failure + # use default settings + endif() +else() + if (EXIT_CODE STREQUAL "0") + # expected: failure, actual: success + if (DEFINED ENV{CI}) + set(TEST_LOG_DIR "${LOG_ROOT}/command_succeeded_but_was_expected_to_fail") + endif() + else() + # expected: failure, actual: failure + if (DEFINED ENV{CI}) + set(TEST_LOG_DIR "${LOG_ROOT}/command_failed_as_expected") + endif() + endif() +endif() + +set(LOG_FILE "${TEST_LOG_DIR}/${LOG_FILE_BASENAME}") + +if (SAVE_LOG) + if(NOT EXISTS "${TEST_LOG_DIR}") + file(MAKE_DIRECTORY "${TEST_LOG_DIR}") + endif() + + file(WRITE "${LOG_FILE}" "${LOG}") +endif() + +if(NOT EXIT_CODE STREQUAL "0") message(FATAL_ERROR "Exit code: ${EXIT_CODE}; log file: ${LOG_FILE}") endif() diff --git a/scripts/cmake/test/NotebookTest.cmake b/scripts/cmake/test/NotebookTest.cmake index 1d2740d80c1c7daefd8907e30a90f28378db4d55..82e6d91475132a2877877fcbf1acf02bfd8ad615 100644 --- a/scripts/cmake/test/NotebookTest.cmake +++ b/scripts/cmake/test/NotebookTest.cmake @@ -98,6 +98,9 @@ function(NotebookTest) endif() endif() + isTestCommandExpectedToSucceed(${TEST_NAME} ${NotebookTest_PROPERTIES}) + message(DEBUG "Is test '${TEST_NAME}' expected to succeed? → ${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}") + add_test( NAME ${TEST_NAME} COMMAND @@ -105,7 +108,9 @@ function(NotebookTest) # TODO: only works if notebook is in a leaf directory -DEXECUTABLE=${Python_EXECUTABLE} "-DEXECUTABLE_ARGS=${_exe_args}" -DWORKING_DIRECTORY=${Data_SOURCE_DIR} - -DLOG_FILE=${PROJECT_BINARY_DIR}/logs/${NotebookTest_NAME_WE}.txt + "-DLOG_ROOT=${PROJECT_BINARY_DIR}/logs" + "-DLOG_FILE_BASENAME=${NotebookTest_NAME_WE}.txt" + "-DTEST_COMMAND_IS_EXPECTED_TO_SUCCEED=${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}" -P ${PROJECT_SOURCE_DIR}/scripts/cmake/test/AddTestWrapper.cmake ) diff --git a/scripts/cmake/test/OgsTest.cmake b/scripts/cmake/test/OgsTest.cmake index 360b4178fcee78e0344a690c64e815a24e256095..900bce228745c182758e997f049ba73bd179a3e4 100644 --- a/scripts/cmake/test/OgsTest.cmake +++ b/scripts/cmake/test/OgsTest.cmake @@ -90,7 +90,7 @@ function(OgsTest) endif() endfunction() -# Add a ctest and sets properties +# Adds a ctest and sets properties macro(_ogs_add_test TEST_NAME) if("${TEST_NAME}" MATCHES "-omp") set(OgsTest_BINARY_DIR "${Data_BINARY_DIR}/${OgsTest_DIR}-omp") @@ -100,6 +100,10 @@ macro(_ogs_add_test TEST_NAME) file(MAKE_DIRECTORY ${OgsTest_BINARY_DIR}) file(TO_NATIVE_PATH "${OgsTest_BINARY_DIR}" OgsTest_BINARY_DIR_NATIVE) string(REPLACE "/" "_" TEST_NAME_UNDERSCORE ${TEST_NAME}) + + isTestCommandExpectedToSucceed(${TEST_NAME} ${OgsTest_PROPERTIES}) + message(DEBUG "Is test '${TEST_NAME}' expected to succeed? → ${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}") + add_test( NAME ${TEST_NAME} COMMAND @@ -107,7 +111,9 @@ macro(_ogs_add_test TEST_NAME) "-DEXECUTABLE_ARGS=${_exe_args}" "-DWRAPPER_COMMAND=${OgsTest_WRAPPER}" -DWORKING_DIRECTORY=${OgsTest_BINARY_DIR} - -DLOG_FILE=${PROJECT_BINARY_DIR}/logs/${TEST_NAME_UNDERSCORE}.txt + "-DLOG_FILE_BASENAME=${TEST_NAME_UNDERSCORE}.txt" + "-DLOG_ROOT=${PROJECT_BINARY_DIR}/logs" + "-DTEST_COMMAND_IS_EXPECTED_TO_SUCCEED=${TEST_COMMAND_IS_EXPECTED_TO_SUCCEED}" -P ${PROJECT_SOURCE_DIR}/scripts/cmake/test/AddTestWrapper.cmake )