Note
Looking for help? We’ve got you covered! ❤️
This tutorial demonstrates how to integrate Mull into a CMake-based project.
We use fmtlib as an example.
Note
If you are new to Mull, then Hello World example is a good starting point.
git clone https://github.com/fmtlib/fmt --depth 1
Create a file fmt/mull.yml
with the following contents:
mutators:
- cxx_add_to_sub
mkdir fmt/build.dir
cd fmt/build.dir
export CXX=clang++-12
cmake \
-DCMAKE_CXX_FLAGS="-O0 -fexperimental-new-pass-manager -fpass-plugin=/usr/lib/mull-ir-frontend-12 -g -grecord-command-line" \
..
make core-test -j
mull-runner-12 ./bin/core-test
You should see similar output:
[info] Using config /tmp/sc-ySbkbNvt3/fmt/mull.yml
[info] Warm up run (threads: 1)
[################################] 1/1. Finished in 11ms
[info] Filter mutants (threads: 1)
[################################] 1/1. Finished in 1ms
[info] Baseline run (threads: 1)
[################################] 1/1. Finished in 8ms
[info] Running mutants (threads: 8)
[################################] 164/164. Finished in 363ms
[info] Survived mutants (160/164):
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2237:14: warning: Survived: Replaced + with - [cxx_add_to_sub]
return len + !len;
^
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2267:24: warning: Survived: Replaced + with - [cxx_add_to_sub]
value = value * 10 + unsigned(*p - '0');
^
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2277:31: warning: Survived: Replaced + with - [cxx_add_to_sub]
prev * 10ull + unsigned(p[-1] - '0') <= max
^
<truncated>
/tmp/sc-ySbkbNvt3/fmt/test/gtest/gmock-gtest-all.cc:12210:36: warning: Survived: Replaced + with - [cxx_add_to_sub]
IsUTF8TrailByte(s[i + 1]) &&
^
/tmp/sc-ySbkbNvt3/fmt/test/gtest/gmock-gtest-all.cc:12211:36: warning: Survived: Replaced + with - [cxx_add_to_sub]
IsUTF8TrailByte(s[i + 2]) &&
^
/tmp/sc-ySbkbNvt3/fmt/test/gtest/gmock-gtest-all.cc:14386:26: warning: Survived: Replaced + with - [cxx_add_to_sub]
argv[j] = argv[j + 1];
^
[info] Mutation score: 2%
[info] Total execution time: 491ms
We’ve got lots of survived mutants.
We can ignore some of them (specifically the ones coming from gtest
and gmock
) by extending the config file as follows:
mutators:
- cxx_add_to_sub
excludePaths:
- .*gtest.*
- .*gmock.*
After rerunning Mull:
$ mull-runner-12 ./bin/core-test
[info] Using config /tmp/sc-ySbkbNvt3/fmt/mull.yml
[info] Warm up run (threads: 1)
[################################] 1/1. Finished in 11ms
[info] Filter mutants (threads: 1)
[################################] 1/1. Finished in 0ms
[info] Baseline run (threads: 1)
[################################] 1/1. Finished in 11ms
[info] Running mutants (threads: 8)
[################################] 96/96. Finished in 312ms
[info] Survived mutants (92/96):
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2237:14: warning: Survived: Replaced + with - [cxx_add_to_sub]
return len + !len;
^
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2267:24: warning: Survived: Replaced + with - [cxx_add_to_sub]
value = value * 10 + unsigned(*p - '0');
^
/tmp/sc-ySbkbNvt3/fmt/include/fmt/core.h:2277:31: warning: Survived: Replaced + with - [cxx_add_to_sub]
prev * 10ull + unsigned(p[-1] - '0') <= max
^
<truncated>
/tmp/sc-ySbkbNvt3/fmt/include/fmt/format.h:2335:40: warning: Survived: Replaced + with - [cxx_add_to_sub]
if (negative) abs_value = ~abs_value + 1;
^
/tmp/sc-ySbkbNvt3/fmt/include/fmt/format.h:2337:34: warning: Survived: Replaced + with - [cxx_add_to_sub]
auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
^
[info] Mutation score: 4%
[info] Total execution time: 368ms
We get fewer mutants, but the number can be reduced even further.
This step left as an exercise for the reader: Keeping mutants under control.
Hint: use Code Coverage filter.