web-dev-qa-db-fra.com

Comment ajouter des tests valgrind à ma cible "test" cmake

J'exécute des tests unitaires en construisant avec ninja puis en exécutant ninja test de mon arbre de génération:

cmake -G Ninja /source/tree
ninja
ninja test

Cependant, pour exécuter valgrind, je dois l'exécuter manuellement:

valgrind rel/path/to/test

J'aimerais que valgrind s'exécute automatiquement lorsque j'exécute ninja test. Selon la documentation de cmake "la configuration des [tests valgrind] est extrêmement facile " mais quand je cours

ctest -D NightlyMemoryCheck

Je reçois juste cette erreur:

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.

J'obtiens une erreur similaire lorsque je suis les instructions de cette SO question:

Comment puis-je faire ctest exécuter un programme avec valgrind sans fléchette?

Je ne sais pas ce qu'est Dart, mais selon le site Web, c'est une sorte de test en ligne.

Clairement extrêmement facile n'est pas assez facile pour moi. Est-ce que quelqu'un connaît une solution si extrêmement simple qu'il faudrait être une sorte de démoniste informatique pour que ça fonctionne pas?

23
quant

Voici un exemple autonome qui montre comment ajouter des tests valgrind à un projet CMake. L'exemple consiste en un seul fichier source C++ main.cpp:

#include <iostream>

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

Le code contient une fuite intentionnelle qui devrait être détectée par valgrind. Nous avons également besoin d'un fichier CMakeLists.txt Qui nécessite CMake> = 2.8:

cmake_minimum_required(VERSION 2.8)

project (ValgrindExample)

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

Ici, il est important d'inclure le module CTest avec include au lieu d'activer simplement les tests avec enable_testing(). Le module CTest prend en charge la configuration de la machine pour pouvoir exécuter des contrôles de mémoire avec des tests (par exemple, il localise l'exécutable valgrind).

Nous pouvons maintenant ouvrir une session Shell dans le dossier du projet et créer une arborescence de construction Ninja:

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

Nous pouvons construire et exécuter des tests sans valgrind de manière régulière:

$ 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

Pour exécuter des tests avec valgrind, nous devons utiliser l'exécutable ctest de CMake avec l'action de test 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 imprime un résumé des résultats de la vérification de la mémoire. La sortie détaillée de valgrind se trouve dans un répertoire temporaire dans l'arborescence de construction:

$ 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)
...

Il n'est pas possible d'exécuter automatiquement valgrind lorsque vous exécutez ninja test Car la cible de test intégrée de CMake ne peut pas être modifiée et exécute toujours les tests de manière régulière. Nous pouvons cependant ajouter une cible CMake personnalisée qui invoque ctest avec l'option -T memcheck Puis imprime le rapport détaillé de 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 Est la version détaillée du commutateur -T.

Nous pouvons alors invoquer les tests valgrind de Ninja avec

$ ninja test_memcheck

et obtenez les résultats comme si nous exécutions valgrind manuellement.

38
sakra