Мне сложно найти ответ на случай nitch с помощью cmocka, проверить malloc на сбой (моделирование) и использовать gcov
Обновление о cmocka + gcov: я заметил, что получаю пустые файлы gcda, как только я имитирую функцию в своих тестах cmocka. Почему? Поиск в Google cmocka и gcov дает результаты, в которых люди говорят об их совместном использовании. Кажется, большинство людей используют CMake, я рассмотрю это позже, но не должно быть никаких причин (которые я могу придумать), которые потребовали бы от меня использования cmake. Почему я не могу просто использовать cmocka с флагами --coverage / -lgcov?
Оригинальный вопрос:
Я пробовал множество комбинаций, в основном основанных на двух основных идеях:
Я пробовал использовать -Wl, - wrap = malloc, поэтому вызовы malloc переносятся. Из моих тестов cmocka я попытался использовать will_return (__ wrap_malloc, (void *) NULL) для имитации сбоя malloc. В моей функции обертывания я использую mock (), чтобы определить, должен ли я возвращать __real_malloc () или NULL. Это дает идеальный эффект, однако я обнаружил, что gcov не может создать файлы gcda, что является одной из причин упаковки malloc, поэтому я могу протестировать сбой malloc И получить результаты покрытия кода. Я чувствую, что играл в грязные игры с символами и испортил вызовы malloc (), вызываемые из других единиц компиляции (gcov? Cmocka?).
Еще один способ, который я попробовал, заключался в использовании gcc -include с использованием #define для malloc для вызова «my malloc» и компиляции моего целевого кода для тестирования с помощью mymalloc.c (определение «my malloc»). Таким образом, #define malloc _mymalloc помогает мне вызывать только «специальный malloc» из целевого тестового кода, оставляя только malloc везде, где он вызывается (т. Е. Оставьте другие объединенные сборки в покое, чтобы они всегда вызывали real malloc). Однако я не знаю, как правильно использовать will_return () и mock () для выявления случаев отказа и случаев успеха. Если я тестирую malloc (), и я получаю то, что хочу, я возвращаю NULL из malloc на основе mock (), возвращающего NULL - все это делается в функции упаковки для malloc, которая вызывается только в целевом коде. Однако, если я хочу вернуть результаты реального malloc, то cmocka не сработает, поскольку я не вернул результат из mock (). Я бы хотел, чтобы cmocka просто удалила результаты из макроса mock () и не заботилась о том, что я не вернул результаты, поскольку мне нужны реальные результаты из malloc (), чтобы тестируемый код мог работать правильно.
Я считаю, что можно объединить тестирование malloc с cmocka и получить результаты gcov.
как бы то ни было, я хотел бы вытянуть следующее или что-то подобное.
int business_code()
{
void* d = malloc(somethingCalculated);
void* e = malloc(somethingElse);
if(!d) return someRecovery();
if(!e) return someOtherRecovery();
return 0;
}
затем выполните тесты cmocka, например
cmocka_d_fail()
{
will_return(malloc, NULL);
int ret = business_code();
assert_int_equal(ret, ERROR_CODE_D);
}
cmocka_e_fail()
{
will_return(malloc, __LINE__); // someway to tell wrapped malloc to give me real memory because the code under test needs it
will_return(malloc, NULL); // I want "d" malloc to succeed but "e" malloc to fail
int ret = business_code();
assert_int_equal(ret, ERROR_CODE_E);
}
Я подхожу к некоторым идеям # define / wrap, которые я пробовал, но в конце концов я либо испортил malloc и заставил gcov не выплевывать мои данные о покрытии, либо у меня нет способа заставить cmocka запускать случаи malloc и возвращать реальные память, т. е. не возвращаться из вызовов mock (). С одной стороны, я мог бы вызвать real malloc из моего тестового драйвера, но и передать его в will_return, но мой test_code не знает размер необходимой памяти, это знает только тестируемый код.
учитывая нехватку времени, я не хочу отказываться от cmocka и моей текущей тестовой инфраструктуры. Я бы рассмотрел другие идеи в будущем, если то, что я хочу, невозможно. То, что я ищу, я знаю, не ново, но я пытаюсь использовать решение cmocka / gcov.
Спасибо