Add fuzz test
This commit is contained in:
2
.clangd
2
.clangd
@@ -1,2 +1,2 @@
|
||||
CompileFlags:
|
||||
Add: [-DENABLE_TESTS, -UNDEBUG]
|
||||
Add: [-DENABLE_TESTS, -UNDEBUG, -DENABLE_FUZZ]
|
||||
|
@@ -14,19 +14,21 @@ target_compile_options(conflict_set PRIVATE -fno-exceptions -fvisibility=hidden)
|
||||
target_link_options(conflict_set PRIVATE -nodefaultlibs -lc -fvisibility=hidden)
|
||||
add_custom_command(TARGET conflict_set POST_BUILD COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:conflict_set>)
|
||||
|
||||
include(CTest)
|
||||
|
||||
# unit test
|
||||
|
||||
add_executable(conflict_set_test ConflictSet.cpp ConflictSet.h)
|
||||
target_compile_definitions(conflict_set_test PRIVATE ENABLE_TESTS)
|
||||
# keep asserts for test
|
||||
target_compile_options(conflict_set_test PRIVATE -UNDEBUG)
|
||||
# Only emit compile warnings for test
|
||||
target_compile_options(conflict_set_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code)
|
||||
|
||||
include(CTest)
|
||||
add_test(NAME conflict_set_test COMMAND conflict_set_test)
|
||||
|
||||
# api smoke tests
|
||||
|
||||
# c89
|
||||
# c99
|
||||
add_executable(conflict_set_c_api_test conflict_set_c_api_test.c ConflictSet.h)
|
||||
target_link_libraries(conflict_set_c_api_test PRIVATE conflict_set)
|
||||
target_compile_options(conflict_set_c_api_test PRIVATE -UNDEBUG)
|
||||
@@ -41,3 +43,17 @@ target_compile_options(conflict_set_cxx_api_test PRIVATE -UNDEBUG)
|
||||
set_property(TARGET conflict_set_cxx_api_test PROPERTY CXX_STANDARD 98)
|
||||
add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test)
|
||||
target_compile_options(conflict_set_cxx_api_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code -Werror)
|
||||
|
||||
# fuzz test
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(HAS_LIB_FUZZER -fsanitize=fuzzer)
|
||||
|
||||
if (HAS_LIB_FUZZER)
|
||||
add_executable(conflict_set_fuzz_test ConflictSet.cpp ConflictSet.h)
|
||||
target_compile_definitions(conflict_set_fuzz_test PRIVATE ENABLE_FUZZ)
|
||||
# keep asserts for test
|
||||
target_compile_options(conflict_set_fuzz_test PRIVATE -UNDEBUG)
|
||||
target_compile_options(conflict_set_fuzz_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code)
|
||||
target_compile_options(conflict_set_fuzz_test PRIVATE -fsanitize=fuzzer)
|
||||
target_link_options(conflict_set_fuzz_test PRIVATE -fsanitize=fuzzer)
|
||||
endif()
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <random>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -825,7 +826,7 @@ void rotate(Node **node, bool dir) {
|
||||
updateMaxVersion(l);
|
||||
}
|
||||
|
||||
void checkParentPointers(Node *node, bool &success) {
|
||||
[[maybe_unused]] void checkParentPointers(Node *node, bool &success) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (node->child[i] != nullptr) {
|
||||
if (node->child[i]->parent != node) {
|
||||
@@ -839,7 +840,7 @@ void checkParentPointers(Node *node, bool &success) {
|
||||
}
|
||||
}
|
||||
|
||||
int64_t checkMaxVersion(Node *node, bool &success) {
|
||||
[[maybe_unused]] int64_t checkMaxVersion(Node *node, bool &success) {
|
||||
int64_t expected = std::max(node->pointVersion, node->rangeVersion);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (node->child[i] != nullptr) {
|
||||
@@ -1214,3 +1215,37 @@ int main(void) {
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FUZZ
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
initFuzz(data, size);
|
||||
|
||||
int64_t writeVersion = 0;
|
||||
ConflictSet::Impl cs{writeVersion};
|
||||
ReferenceImpl refImpl{writeVersion};
|
||||
|
||||
while (gArbitrary.hasEntropy()) {
|
||||
Arena arena;
|
||||
int numWrites = gArbitrary.bounded(10);
|
||||
int64_t v = ++writeVersion;
|
||||
auto *writes = new (arena) ConflictSet::WriteRange[numWrites];
|
||||
std::set<int> keys;
|
||||
while (int(keys.size()) < numWrites) {
|
||||
keys.insert(gRandom.bounded(100));
|
||||
}
|
||||
auto iter = keys.begin();
|
||||
for (int i = 0; i < numWrites; ++i) {
|
||||
writes[i].begin = toKey(arena, *iter++);
|
||||
writes[i].end.len = 0;
|
||||
writes[i].writeVersion = v;
|
||||
}
|
||||
cs.addWrites(writes, numWrites);
|
||||
refImpl.addWrites(writes, numWrites);
|
||||
bool success = checkCorrectness(cs.root, refImpl);
|
||||
if (!success) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user