Найти в Дзене
Протестировал

Обычно для оценки степени покрытия кода фаззинг-тестированием используют покрытие по строкам/функциями и редко по ветвлениям

Метрика покрытия MC/DC редко используется для оценка покрытия регресионными тестами вообще и фаззинга в частности, хотя она позволяет получить доказательство того, что логика надежно тестируется в коде. Я сделал патч, чтобы можно было для кода PUC Rio Lua и LuaJIT собирать MC/DC покрытие, мне было интересно узнать значения метрики для этих двух проектов при тестировании нашими фаззинг-тестами. Поддержка покрытия MC/DC уже есть и в GCC и в Clang (18+ и это не возраст, а версия), так как тесты по умолчанию собираются с libFuzzer, то я использовал реализацию из LLVM/Clang. Результаты такие: Общее покрытие MC/DC для кода LuaJIT 23%, некоторые файлы покрыты лучше других, топ-3: lj_parse.c - 95%, lj_buf.c - 88%, lj_str.c/lj_tab.c/lib_aux.c - 75%. Кажется здесь есть над чем подумать - файл для сборщика мусора покрыт на 97% по строкам и только 49% по MC/DC или lj_record.c по строкам 80% и 20% по MC/DC. В этих компонентах логика похоже плохо покрыта. Общее покрытие MC/DC для кода PUC Rio Lua

Обычно для оценки степени покрытия кода фаззинг-тестированием используют покрытие по строкам/функциями и редко по ветвлениям. Метрика покрытия MC/DC редко используется для оценка покрытия регресионными тестами вообще и фаззинга в частности, хотя она позволяет получить доказательство того, что логика надежно тестируется в коде. Я сделал патч, чтобы можно было для кода PUC Rio Lua и LuaJIT собирать MC/DC покрытие, мне было интересно узнать значения метрики для этих двух проектов при тестировании нашими фаззинг-тестами. Поддержка покрытия MC/DC уже есть и в GCC и в Clang (18+ и это не возраст, а версия), так как тесты по умолчанию собираются с libFuzzer, то я использовал реализацию из LLVM/Clang. Результаты такие:

Общее покрытие MC/DC для кода LuaJIT 23%, некоторые файлы покрыты лучше других, топ-3: lj_parse.c - 95%, lj_buf.c - 88%, lj_str.c/lj_tab.c/lib_aux.c - 75%. Кажется здесь есть над чем подумать - файл для сборщика мусора покрыт на 97% по строкам и только 49% по MC/DC или lj_record.c по строкам 80% и 20% по MC/DC. В этих компонентах логика похоже плохо покрыта.

Общее покрытие MC/DC для кода PUC Rio Lua 23%, топ-3 файлов с большим покрытием: lstring.c/lzio.c - 100%, lopcodes.c - 83%.

Оговорюсь, что приведенные цифры могут неточно отражать действительность по некоторым причинам: в OSS Fuzz покрытие кода Lua на уровне 92% по строкам на протяжении наверное трёх лет или больше, то есть мой корпус для PUC Rio Lua при измерении был не совсем актуальный, при сборке PUC Rio Lua и LuaJIT компилятор часто показывал сообщения "unsupported MC/DC boolean expression; contains an operation with a nested boolean expression", возможно это повлияло на точность измерений.

Интересно, что Ричард Хипп даже противопоставляет фаззинг и 100% покрытие по MC/DC:

Фаззинг-тестирование и 100% тестирование MC/DC находятся в противоречии друг с другом. Код, протестированный на 100% MC/DC, будет более уязвим к проблемам, выявляемым фаззингом, а код, хорошо работающий во время фаззинг-тестирования, будет иметь (значительно) меньший процент MC/DC, чем 100%. Потому что тестирование MC/DC препятствует созданию защитного кода с недоступными ветвями, но без защитного кода фаззер с большей вероятностью найдет путь, который вызовет проблемы. Хотя фаззинговое тестирование и 100% MC/DC-тестирование находятся в противоречии, они не полностью противоречат друг другу. Тот факт, что набор тестов SQLite тестирует на 100% MC/DC, означает, что когда фаззеры находят проблемы, эти проблемы можно быстро исправить с минимальным риском появления новых ошибок.