Skip to content

Commit

Permalink
added triangulator fuzzer (#620)
Browse files Browse the repository at this point in the history
* added triangulator fuzzer

* added easy to use minimizer script

* update readme

* added rounding
  • Loading branch information
pca006132 authored Nov 25, 2023
1 parent 1f8e803 commit f683e8c
Show file tree
Hide file tree
Showing 7 changed files with 4,931 additions and 4,691 deletions.
15 changes: 14 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,25 @@ set(MANIFOLD_PAR "NONE" CACHE STRING "Parallel backend, either \"TBB\" or \"NONE
set(MANIFOLD_FLAGS "" CACHE STRING "Manifold compiler flags")
option(MANIFOLD_EXPORT "Build mesh export (via assimp) utility library" OFF)
option(MANIFOLD_TEST "Enable testing suite" ON)
# fuzztest is a rather large dependency
option(MANIFOLD_FUZZ "Enable fuzzing tests" OFF)
option(MANIFOLD_DEBUG "Enable debug tracing/timing" OFF)

option(MANIFOLD_PYBIND "Build python bindings" ON)
option(MANIFOLD_CBIND "Build C (FFI) bindings" OFF)
option(MANIFOLD_JSBIND "Build js binding" ${EMSCRIPTEN})

if(MANIFOLD_FUZZ)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
message(FATAL_ERROR "fuzztest only supports clang" )
endif()
# we should enable debug checks
set(MANIFOLD_DEBUG ON)
# enable fuzztest fuzzing mode
set(FUZZTEST_FUZZING_MODE ON)
# address sanitizer required
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -fsanitize=address")
endif()

option(TRACY_ENABLE "Use tracy profiling" OFF)
option(TRACY_MEMORY_USAGE "Track memory allocation with tracy (expensive)" OFF)
option(BUILD_TEST_CGAL "Build CGAL performance comparisons" OFF)
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,22 @@ For more detailed documentation, please refer to the C++ API.

Contributions are welcome! A lower barrier contribution is to simply make a PR that adds a test, especially if it repros an issue you've found. Simply name it prepended with DISABLED_, so that it passes the CI. That will be a very strong signal to me to fix your issue. However, if you know how to fix it yourself, then including the fix in your PR would be much appreciated!

## Profiling
### Profiling

There is now basic support for the [Tracy profiler](https://github.com/wolfpld/tracy) for our tests.
To enable tracing, compile with `-DTRACY_ENABLE=on` cmake option, and run the test with Tracy server running.

### Fuzzing Support

We use https://github.com/google/fuzztest for fuzzing the triangulator.

To enable fuzzing, make sure that you are using clang compiler (`-DCMAKE_CXX_COMPILER=clang -DCMAKE_C_COMPILER=clang`), running Linux, and enable fuzzing support by setting `-DMANIFOLD_FUZZ=ON`.

To run the fuzzer and minimize testcase, do
```
../minimizer.sh ./test/polygon_fuzz --fuzz=PolygonFuzz.TriangulationNoCrash
```

## About the author

This library was started by [Emmett Lalish](https://elalish.blogspot.com/). I am currently a Google employee and this is my 20% project, not an official Google project. At my day job I'm the maintainer of [\<model-viewer\>](https://modelviewer.dev/). I was the first employee at a 3D video startup, [Omnivor](https://www.omnivor.io/), and before that I worked on 3D printing at Microsoft, including [3D Builder](https://www.microsoft.com/en-us/p/3d-builder/9wzdncrfj3t6?activetab=pivot%3Aoverviewtab). Originally an aerospace engineer, I started at a small DARPA contractor doing seedling projects, one of which became [Sea Hunter](https://en.wikipedia.org/wiki/Sea_Hunter). I earned my doctorate from the University of Washington in control theory and published some [papers](https://www.researchgate.net/scientific-contributions/75011026_Emmett_Lalish).
59 changes: 59 additions & 0 deletions minimizer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash

# Modified from https://github.com/google/fuzztest/blob/main/tools/minimizer.sh
# If you want to use a specific reproducer, pass it in FUZZTEST_MINIMIZE_REPRODUCER
# environment variable.
# Otherwise, just run it as
# $ ./minimizer.sh ./build/test/polygon_fuzz --fuzz=PolygonFuzz.TriangulationNoCrash
# If you want to kill it, try SIGKILL, SIGTERM is not very useful
# If you want to end the loop early, rename $(pwd)/reproducers into something
# else...

if [ -z "${FUZZTEST_MINIMIZE_REPRODUCER}"]; then
mkdir -p $(pwd)/reproducers
FUZZTEST_REPRODUCERS_OUT_DIR=$(pwd)/reproducers "$@"
wildcard="$(pwd)/reproducers/*"
reproducers=($wildcard)
FUZZTEST_MINIMIZE_REPRODUCER="${reproducers[0]}"
fi
readonly ORIGINAL_REPRODUCER="${FUZZTEST_MINIMIZE_REPRODUCER}"

for i in {0001..9999}; do
echo
echo "╔════════════════════════════════════════════════╗"
echo "║ Minimization round: ${i}"
echo "╚════════════════════════════════════════════════╝"
echo "Note that to terminate early, simply move $ORIGINAL_REPRODUCER to somewhere else..."
echo

if [ ! -f $ORIGINAL_REPRODUCER ]; then
echo "Terminated by the user"
break
fi

TEMP_DIR=$(mktemp -d)
FUZZTEST_REPRODUCERS_OUT_DIR="${TEMP_DIR}" \
FUZZTEST_MINIMIZE_REPRODUCER="${FUZZTEST_MINIMIZE_REPRODUCER}" \
"$@"

if [ $? -eq 130 ]; then
echo
echo "╔═══════════════════════════════════════════════╗"
echo "║ Minimization terminated. ║"
echo "╚═══════════════════════════════════════════════╝"
echo
echo "Find the smallest reproducer at:"
echo
echo "${FUZZTEST_MINIMIZE_REPRODUCER}"

rm -rf "${TEMP_DIR}"
break
fi

SMALLER_REPRODUCER=$(find "${TEMP_DIR}" -type f)
NEW_NAME="${ORIGINAL_REPRODUCER}-min-${i}"
mv "${SMALLER_REPRODUCER}" "${NEW_NAME}"
FUZZTEST_MINIMIZE_REPRODUCER="${NEW_NAME}"

rm -rf "${TEMP_DIR}"
done
16 changes: 16 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

project(manifold_test)

set(CMAKE_CXX_STANDARD 17)
enable_testing()

set(SOURCE_FILES polygon_test.cpp cross_section_test.cpp manifold_test.cpp boolean_test.cpp sdf_test.cpp samples_test.cpp test_main.cpp)
Expand Down Expand Up @@ -44,6 +45,21 @@ endif()
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} polygon GTest::gtest_main manifold sdf samples cross_section)

if(MANIFOLD_FUZZ)
FetchContent_Declare(fuzztest
GIT_REPOSITORY https://github.com/google/fuzztest.git
# note that if commit hash is used, it cannot be a shallow clone
GIT_TAG 2606e04a43e5a7730e437a849604a61f1cb0ff28
GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(fuzztest)
fuzztest_setup_fuzzing_flags()
add_executable(polygon_fuzz polygon_fuzz.cpp)
target_link_libraries(polygon_fuzz PUBLIC polygon)
link_fuzztest(polygon_fuzz)
gtest_discover_tests(polygon_fuzz)
endif()

if(MANIFOLD_CBIND)
target_link_libraries(${PROJECT_NAME} manifoldc)
endif()
Expand Down
Loading

0 comments on commit f683e8c

Please sign in to comment.