Как добавить тесты valgrind к моей целевой программе "тест"

Я запускаю модульные тесты, создавая с помощью ninja, а затем запускаю ninja test из моего дерева сборки:

cmake -G Ninja /source/tree
ninja
ninja test

Однако для запуска valgrind мне нужно запустить его вручную:

valgrind rel/path/to/test

Я бы хотел, чтобы valgrind запускался автоматически при запуске ninja test. Согласно документации cmake "настройка [тестов valgrind] чрезвычайно простая", но когда я запускаю

ctest -D NightlyMemoryCheck

Я просто получаю эту ошибку:

Cannot find file: /home/arman/tinman/deb/DartConfiguration.tcl
   Site: 
   Build name: (empty)
WARNING: No nightly start time found please set in CTestConfig.cmake or DartConfig.cmake
Problem initializing the dashboard.

Я получаю аналогичную ошибку, следуя инструкциям из этого вопроса SO:

Как заставить ctest запускать программу с valgrind без дротика?

Я не знаю, что такое dart, но, согласно веб-сайту, это какой-то онлайн-тест doodad.

Ясно, что очень легко для меня нелегко. Кто-нибудь знает о решении, которое настолько просто, что вам нужно быть чем-то вроде чернокнижника, чтобы он не работал?

Ответ 1

Вот пример, который показывает, как добавлять тесты valgrind в проект CMake. Пример состоит из одного исходного файла С++ main.cpp:

#include <iostream>

int main()
{
    double* leak = new double[10];
    std::cout << "Hello!" << std::endl;
}

Код содержит преднамеренную утечку, которая должна быть поднята valgrind. Нам также нужен файл CMakeLists.txt, который требует CMake >= 2.8:

cmake_minimum_required(VERSION 2.8)

project (ValgrindExample)

include (CTest)
add_executable(example main.cpp)
add_test(example_test example)

Здесь важно включить модуль CTest с include вместо того, чтобы включать тесты с enable_testing(). Модуль CTest позаботится о настройке оборудования для возможности проверки памяти с помощью тестов (например, он находит исполняемый файл valgrind).

Теперь мы можем открыть сеанс оболочки в папке проекта и создать дерево сборки Ninja:

$ mkdir build; cd build
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..

Мы можем строить и запускать тесты без valgrind обычным способом:

$ ninja
[2/2] Linking CXX executable example
$ ninja test
[0/1] Running tests...
...
100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.01 sec

Для запуска тестов с valgrind мы должны использовать исполняемый файл CMake ctest с тестовым действием memcheck:

$ ctest -T memcheck
...
1/1 MemCheck #1: example_test .....................   Passed    0.77 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.77 sec
-- Processing memory checking output: 
Memory checking results:
Memory Leak - 2

ctest распечатывает сводку результатов проверки памяти. Подробный вывод valgrind находится во временном каталоге дерева сборки:

$ cat ./Testing/Temporary/MemoryChecker.*.log
==4565== 80 bytes in 1 blocks are definitely lost in loss record 37 of 64
==4565==    at 0x10000B681: malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==4565==    by 0x1000507DD: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==4565==    by 0x100000F93: main (main.cpp:5)
...

Невозможно автоматически запустить valgrind при запуске ninja test, потому что встроенная тестовая цель CMake не может быть изменена и всегда запускает тесты обычным способом. Однако мы можем добавить пользовательскую цель CMake, которая вызывает ctest с опцией -T memcheck, а затем печатает подробный отчет valgrind:

add_custom_target(test_memcheck
    COMMAND ${CMAKE_CTEST_COMMAND} 
        --force-new-ctest-process --test-action memcheck
    COMMAND cat "${CMAKE_BINARY_DIR}/Testing/Temporary/MemoryChecker.*.log")

--test-action является вербальной версией коммутатора -T.

Затем мы можем вызвать тестирование valgrind от Ninja с помощью

$ ninja test_memcheck

и получите результаты, как если бы мы выполнили команду valgrind вручную.