вы можете это сделать
while 2 in x:
x.remove(2)
CTest предоставляет только базовые, обычно используемые интерпретаторы для результата тестовых программ. Для реализации других интерпретаторов вы можете написать простую программу / скрипт, который обертывает тест и интерпретирует его результат по мере необходимости. Например. C (для Linux):
test_that_crash.c:
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main(int argc, char** argv)
{
pid_t pid = fork();
if(pid == -1)
{
// fork fails
return 1;
}
else if(pid)
{
// Parent - wait child and interpret its result
int status = 0;
wait(&status);
if(WIFSIGNALED(status)) return 0; // Signal-terminated means success
else return 1;
}
else
{
// Child - execute wrapped command
execvp(argv[1], argv + 1);
exit(1);
}
}
Эта программа может использоваться в CMake следующим образом:
CMakeLists.txt:
# Compile our wrapper
add_executable(test_that_crash test_that_crash.c)
# Similar to add_test(name command), but test is assumed successfull only if it is crashed(signalled)
macro(add_test_crashed name command)
# Use generic flow of add_test() command for automatically recognize our executable target
add_test(NAME ${name} COMMAND test_that_crash ${command} ${ARGN})
endmacro(add_test_crashed)
# ...
# Add some test, which should crash
add_test_crashed(clang.crash.1 <clang-executable> <clang-args>)
Существует также специфическое для клана решение: настроить его способ выхода с помощью переменной среды ASAN_OPTIONS
. (См. https://github.com/google/sanitizers/wiki/AddressSanitizerFlags .) Для этого установите для переменной среды ASAN_OPTIONS
значение abort_on_error=0
. Когда дезинфицирующее средство для адреса обнаруживает проблему, тогда процесс будет работать _exit(1)
, а не (предположительно) abort()
, и, таким образом, он, кажется, прекратит свое действие. Затем вы можете выбрать это, используя механизм cmake WILL_FAIL
. (Пока неясно, почему OS X и Linux отличаются в этом отношении - но там вы идете.)
В качестве бонуса тест выходит из строя намного быстрее.
(Еще одна удобная опция который может улучшить время обработки при прохождении через cmake, заключается в том, чтобы установить ASAN_SYMBOLIZER_PATH
на пустое значение, которое останавливает дезинфицирующее средство адреса, символизирующее трассировку стека. Символирование занимает некоторое время, но нет смысла делать это при запуске через cmake, (см. вывод.)
Вместо этого вручную, я создал скрипт Python, который соответствующим образом устанавливает среду на OS X (ничего не делая на Linux) и вызывает тест. Затем я добавляю каждый асин-тест с использованием макроса по линии ответа Цыварева.
macro(add_asan_test basename)
add_executable(${basename} ${basename}.c)
add_test(NAME test/${basename} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/wrap_clang_sanitizer_test.py -a $<TARGET_FILE:${basename}>)
set_tests_properties(test/${basename} PROPERTIES WILL_FAIL TRUE)
endmacro()
Это дает простой проход / сбой как можно быстрее. Я имею обыкновение исследовать сбои, запустив соответствующий тест из оболочки вручную и изучая вывод, и в этом случае я получаю трассировку стека как обычно (и факт, выходящий из abort
, немного медленнее, меньше проблемы).
(Аналогичные варианты для других дезинфицирующих средств, но я их не исследовал.)