From 1b92b7b87d244f2bf7a464f2020cc5f05a66380c Mon Sep 17 00:00:00 2001 From: Simon Liu <331435+monadbobo@users.noreply.github.com> Date: Wed, 11 Dec 2019 18:52:34 +0800 Subject: [PATCH] Issue #714 Added the fuzzy test. (#1011) * Issue #714 Added the fuzzy test. sumarry: 1. Added a new parameter "fuzzer" to nebula_add_test(cmake). Turn on this parameter indicates that the current test is a fuzzy test. 2. Currently only a simple fuzzy test has been added for paser module. 3. The current fuzzy test only supports Clang, so if the compiler was gcc it will skip. * Move the fuzzer test from the "test" directory to the "fuzzing" directory. * added the missed cmake file. * 1. Added a document for fuzz test 2. Added the AFL dictionary for fuzzy test * Fixed conflict. * address @dutor's comment. * Add a new cmake option ENABLE_FUZZ_TEST to control whether to enable the fuzz test. --- CMakeLists.txt | 19 ++- src/parser/test/CMakeLists.txt | 4 + src/parser/test/fuzzing/CMakeLists.txt | 7 + src/parser/test/fuzzing/ParserFuzzer.cpp | 16 ++ src/parser/test/fuzzing/README.md | 11 ++ src/parser/test/fuzzing/nebula.dict | 180 +++++++++++++++++++++++ 6 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 src/parser/test/fuzzing/CMakeLists.txt create mode 100644 src/parser/test/fuzzing/ParserFuzzer.cpp create mode 100644 src/parser/test/fuzzing/README.md create mode 100644 src/parser/test/fuzzing/nebula.dict diff --git a/CMakeLists.txt b/CMakeLists.txt index b29e315c..302dfcc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,10 +29,12 @@ option(ENABLE_CCACHE "Whether to use ccache to speed up compiling" ON) option(ENABLE_ASAN "Whether to turn AddressSanitizer ON or OFF" OFF) option(ENABLE_TESTING "Whether to turn unit test ON or OFF" ON) option(ENABLE_UBSAN "Whether to turn Undefined Behavior Sanitizer ON or OFF" OFF) +option(ENABLE_FUZZ_TEST "Whether to turn Fuzz Test ON or OFF" OFF) message(STATUS "ENABLE_ASAN: ${ENABLE_ASAN}") message(STATUS "ENABLE_TESTING: ${ENABLE_TESTING}") message(STATUS "ENABLE_UBSAN: ${ENABLE_UBSAN}") +message(STATUS "ENABLE_FUZZ_TEST: ${ENABLE_FUZZ_TEST}") if (ENABLE_NATIVE) @@ -237,6 +239,13 @@ if(ENABLE_UBSAN) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") endif() +if(ENABLE_FUZZ_TEST) + check_cxx_compiler_flag("-fsanitize=fuzzer" ENABLE_FUZZ_OK) + if (NOT ENABLE_FUZZ_OK) + MESSAGE(FATAL_ERROR "The compiler does not support fuzz testing") + endif() +endif() + macro(nebula_add_executable) cmake_parse_arguments( nebula_exec # prefix @@ -259,7 +268,7 @@ endmacro() macro(nebula_add_test) cmake_parse_arguments( nebula_test # prefix - "DISABLED" # <options> + "DISABLED;FUZZER" # <options> "NAME" # <one_value_args> "SOURCES;OBJECTS;LIBRARIES" # <multi_value_args> ${ARGN} @@ -272,7 +281,13 @@ macro(nebula_add_test) LIBRARIES ${nebula_test_LIBRARIES} ) - if (NOT ${nebula_test_DISABLED}) + if (${nebula_test_FUZZER}) + #Currently only Clang supports fuzz test + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set_target_properties(${nebula_test_NAME} PROPERTIES COMPILE_FLAGS "-g -fsanitize=fuzzer") + set_target_properties(${nebula_test_NAME} PROPERTIES LINK_FLAGS "-fsanitize=fuzzer") + endif() + elseif (NOT ${nebula_test_DISABLED}) string(REGEX REPLACE "${CMAKE_SOURCE_DIR}/src/(.*)/test" "\\1" test_group ${CMAKE_CURRENT_SOURCE_DIR}) add_test(NAME ${nebula_test_NAME} COMMAND ${nebula_test_NAME}) set_tests_properties(${nebula_test_NAME} PROPERTIES LABELS ${test_group}) diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt index ef6d5b05..b3e0f5b7 100644 --- a/src/parser/test/CMakeLists.txt +++ b/src/parser/test/CMakeLists.txt @@ -38,3 +38,7 @@ nebula_add_executable( OBJECTS ${PARSER_TEST_LIBS} LIBRARIES follybenchmark boost_regex ${THRIFT_LIBRARIES} wangle ) + +if(ENABLE_FUZZ_TEST) + nebula_add_subdirectory(fuzzing) +endif() diff --git a/src/parser/test/fuzzing/CMakeLists.txt b/src/parser/test/fuzzing/CMakeLists.txt new file mode 100644 index 00000000..a408d77e --- /dev/null +++ b/src/parser/test/fuzzing/CMakeLists.txt @@ -0,0 +1,7 @@ +nebula_add_test( + NAME parser_fuzzer + FUZZER ON + SOURCES ParserFuzzer.cpp + OBJECTS ${PARSER_TEST_LIBS} + LIBRARIES ${THRIFT_LIBRARIES} wangle +) diff --git a/src/parser/test/fuzzing/ParserFuzzer.cpp b/src/parser/test/fuzzing/ParserFuzzer.cpp new file mode 100644 index 00000000..0b98b949 --- /dev/null +++ b/src/parser/test/fuzzing/ParserFuzzer.cpp @@ -0,0 +1,16 @@ +/* Copyright (c) 2019 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License, + * attached with Common Clause Condition 1.0, found in the LICENSES directory. + */ + +#include "base/Base.h" +#include "parser/GQLParser.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + nebula::GQLParser parser; + const char* ptr = reinterpret_cast<const char*>(data); + std::string query = {ptr, size}; + auto result = parser.parse(query); + return 0; +} diff --git a/src/parser/test/fuzzing/README.md b/src/parser/test/fuzzing/README.md new file mode 100644 index 00000000..eeeb5695 --- /dev/null +++ b/src/parser/test/fuzzing/README.md @@ -0,0 +1,11 @@ +# Nebula Graph Database fuzz testing + +Nebula-graph uses [libfuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz test. +If you want to use fuzz test, then you need to use the [Clang](https://clang.llvm.org/) to compile Nebula. +In order to better show the test results, it is recommended to enable the addresssanitizer(-DENABLE_ASAN=ON) option when compiling. + +# Running fuzz tests locally + +``` shell + ./parser_fuzzer -dict=nebula.dict +``` diff --git a/src/parser/test/fuzzing/nebula.dict b/src/parser/test/fuzzing/nebula.dict new file mode 100644 index 00000000..70a054b2 --- /dev/null +++ b/src/parser/test/fuzzing/nebula.dict @@ -0,0 +1,180 @@ +# AFL dictionary for NGQL +# usage: ./parser_fuzzer -dict=nebula.dict +# +# Copyright (c) 2019 vesoft inc. All rights reserved. +# +# This source code is licensed under Apache 2.0 License, +# attached with Common Clause Condition 1.0, found in the LICENSES directory. + + +function_abs=" abbs(1)" +function_floor=" floor(1.1)" +function_ceil=" ceil(1.1)" +function_round=" round(1, 1)" +function_sqrt=" sqrt(1)" +function_cbrt=" cbrt(1)" +function_hypot=" hypot(1, 1)" +function_pow=" pow(1, 1)" +function_exp=" exp(1)" +function_exp2=" exp(1)" +function_log=" log(1)" +function_log2=" log2(1)" +function_log10=" log10(1)" +function_sin=" sin(1)" +function_asin=" asin(1)" +function_cos=" cos(1)" +function_acos=" acos(1)" +function_tan=" tan(1)" +function_atan=" atan(1)" +function_rand32=" rand32(1, 1)" +function_rand64=" rand64(1, 1)" +function_now=" now()" +function_strcasecmp=" strcasecmp(1, 1)" +function_lower=" lower(1)" +function_upper=" upper(1)" +function_length=" length(1)" +function_trim=" trim(1)" +function_ltrim=" ltrim(1)" +function_rtrim=" rtrim(1)" +function_left=" left(1, 1)" +function_right=" right(1, 1)" +function_substr=" substr(1,1,1)" +function_hash=" hash(1)" +function_now=" now()" + +keyword_GO="GO" +keyword_AS="AS" +keyword_TO="TO" +keyword_OR="OR" +keyword_AND="AND" +keyword_XOR="XOR" +keyword_USE="USE" +keyword_SET="SET" +keyword_FROM="FROM" +keyword_WHERE="WHERE" +keyword_MATCH="MATCH" +keyword_INSERT="INSERT" +keyword_VALUES="VALUES" +keyword_YIELD="YIELD" +keyword_RETURN="RETURN" +keyword_CREATE="CREATE" +keyword_DESCRIBE="DESCRIBE" +keyword_DESC="DESC" +keyword_VERTEX="VERTEX" +keyword_EDGE="EDGE" +keyword_EDGES="EDGES" +keyword_UPDATE="UPDATE" +keyword_UPSERT="UPSET" +keyword_WHEN="WHEN" +keyword_DELETE="DELETE" +keyword_FIND="FIND" +keyword_ALTER="ALTER" +keyword_STEPS="STEPS" +keyword_OVER="OVER" +keyword_UPTO="UPTO" +keyword_REVERSELY="REVERSELY" +keyword_SPACE="SPACE" +keyword_SPACES="SPACES" +keyword_INT="INT" +keyword_BIGINT="BIGINT" +keyword_DOUBLE="DOUBLE" +keyword_STRING="STRING" +keyword_BOOL="BOOL" +keyword_TAG="TAG" +keyword_TAGS="TAGS" +keyword_UNION="UNION" +keyword_INTERSECT="INTERSECT" +keyword_MINUS="MINUS" +keyword_NO="NO" +keyword_OVERWRITE="OVERWRITE" +keyword_TRUE="TRUE" +keyword_FALSE="FALSE" +keyword_SHOW="SHOW" +keyword_ADD="ADD" +keyword_HOSTS="HOSTS" +keyword_TIMESTAMP="TIMESTAMP" +keyword_PARTITION="PARTITION" +keyword_REPLICA_F="REPLICA_F" +keyword_DROP="DROP" +keyword_REMOVE="REMOVE" +keyword_IF="IF" +keyword_NOT="NOT" +keyword_EXISTS="EXISTS" +keyword_WITH="WITH" +keyword_FIRSTNAME="FIRSTNAME" +keyword_LASTNAME="LASTNAME" +keyword_EMAIL="EMAIL" +keyword_PHONE="PHONE" +keyword_USER="USER" +keyword_USERS="USERS" +keyword_PASSWORD="PASSWORD" +keyword_CHANGE="CHANGE" +keyword_ROLE="ROLE" +keyword_GOD="GOD" +keyword_ADMIN="ADMIN" +keyword_GUEST="GUEST" +keyword_GRANT="GRANT" +keyword_REVOKE="REVOKE" +keyword_ON="ON" +keyword_ROLES="ROLES" +keyword_BY="BY" +keyword_IN="IN" +keyword_TTL_DURAT="TTL_DURAT" +keyword_TTL_COL="TTL_COL" +keyword_DOWNLOAD="DOWNLOAD" +keyword_HDFS="HDFS" +keyword_ORDER="ORDER" +keyword_INGEST="INGEST" +keyword_ASC="ASC" +keyword_DISTINCT="DISTINCT" +keyword_VARIABLES="VARIABLES" +keyword_GET="GET" +keyword_GRAPH="GRAPH" +keyword_META="META" +keyword_STORAGE="STORAGE" +keyword_FETCH="FETCH" +keyword_PROP="PROP" +keyword_ALL="ALL" +keyword_BALANCE="BALANCE" +keyword_LEADER="LEADER" +keyword_OF="OF" + +operator_PLUS=" +" +operator_MINUS=" -" +operator_MUL=" *" +operator_DIV=" /" +operator_MOD=" %" +operator_NOT=" !" +operator_XOR=" ^" +operator_LT=" < " +operator_LE=" <= " +operator_GT=" > " +operator_GE=" >= " +operator_EQ=" == " +operator_NE=" != " +operator_AND=" && " +operator_OR=" || " +operator_LARROW="<-" +operator_RARROW="->" +operator_COMMA="." +operator_PIPE=" | " +operator_PIPE_START=" $$." +operator_PIPE_END=" $^." +operator_INPUT_REF=" $-." +operator_AT=" @" + +RESERVE_PROPID="._id " +RESERVE_PROPSRC="._src " +RESERVE_PROPDST="._dst " +RESERVE_PROPRANK="._rank " + +snippet_comment=" /* */" +snippet_semicolon=" ;" +snippet_over_star=" over * " +snippet_timestamp=" 1551331900" +snippet_ref=" a.b" +snippet_go=" go from 1 over dummy " +snippet_where=" go from 1 over dummy where " +snippet_yield=" go from 1 over dummy,like where like._id > 10 yield " +snippet_yield2=" go from 1 over dummy,like where like._id > 10 yield like.a " + -- GitLab