diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index 9f2bb13a..2ffdc3af 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -11,4 +11,4 @@ jobs: submodules: 'recursive' - name: Run native tests working-directory: ./app/src/main/jni/tests - run: ./run_tests.sh + run: make run_tests diff --git a/app/src/main/jni/tests/CMakeLists.txt b/app/src/main/jni/tests/CMakeLists.txt index aebb8f6b..9d6fc7ed 100644 --- a/app/src/main/jni/tests/CMakeLists.txt +++ b/app/src/main/jni/tests/CMakeLists.txt @@ -4,7 +4,7 @@ option(FUZZING "Build for Fuzz Testing" OFF) set(CMAKE_C_COMPILER "clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer") -project(test) +project(tests) cmake_minimum_required(VERSION 3.18.1) if(FUZZING) @@ -14,6 +14,7 @@ if(FUZZING) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFUZZING -g ${LIB_FUZZING_ENGINE}") else() + # Tests set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") endif() @@ -25,39 +26,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) include_directories(${ROOTDIR}/submodules/zdtun) include_directories(${ROOTDIR}/submodules/nDPI/src/include) -include(CTest) - -# Target to run tests and build them if necessary -add_custom_target(build_tests) -add_custom_target(run_tests COMMAND CTEST_OUTPUT_ON_FAILURE=1 ${CMAKE_CTEST_COMMAND}) -add_dependencies(run_tests build_tests) - -# build_group(target) -macro(build_group) - add_executable(${ARGV0} ${ARGV0}.c test_utils.c) - add_dependencies(${ARGV0} libpcapd.so) - add_dependencies(build_tests ${ARGV0}) - - target_link_libraries(${ARGV0} capture) -endmacro() - -# Fuzz targets if(FUZZING) - add_executable(fuzz_pcapd fuzz_pcapd.c) - target_link_libraries(fuzz_pcapd libpcapd.so) + add_subdirectory(fuzz) +else() + add_subdirectory(test) endif() - -# Tests -build_group(pcap_reader) - -add_test(NAME dpi_extract COMMAND ./dpi extract) -build_group(dpi) - -add_test(NAME blacklist_match COMMAND ./blacklist match) -add_test(NAME blacklist_detection COMMAND ./blacklist detection) -build_group(blacklist) - -add_test(NAME dump_api_snaplen COMMAND ./dump_api snaplen) -add_test(NAME dump_api_max_pkts_flow COMMAND ./dump_api max_pkts_per_flow) -add_test(NAME dump_api_max_size COMMAND ./dump_api max_dump_size) -build_group(dump_api) diff --git a/app/src/main/jni/tests/Makefile b/app/src/main/jni/tests/Makefile new file mode 100644 index 00000000..bdeb89ed --- /dev/null +++ b/app/src/main/jni/tests/Makefile @@ -0,0 +1,16 @@ +.PHONY: clean run_tests fuzz fuzz_pcapd + +clean: + rm -rf build + +run_tests: + mkdir -p build/tests + cd build && cmake .. && $(MAKE) run_tests + +fuzz: + mkdir -p build/${FUZZ_TARGET} + ( cd build/${FUZZ_TARGET} && cmake ../.. -DFUZZING=1 && make -j$(nproc) ${FUZZ_TARGET} ) + ( cd build/${FUZZ_TARGET} && mkdir -p ../CORPUS && fuzz/${FUZZ_TARGET} ../CORPUS ../../../../../../../submodules/nDPI/tests/pcap ../../pcap >/dev/null ) + +fuzz_pcapd: + $(MAKE) FUZZ_TARGET=fuzz_pcapd fuzz diff --git a/app/src/main/jni/tests/README.md b/app/src/main/jni/tests/README.md new file mode 100644 index 00000000..7bc8b086 --- /dev/null +++ b/app/src/main/jni/tests/README.md @@ -0,0 +1,15 @@ +Tests and fuzzers for the native code of PCAPdroid. + +The tests are built with the [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) to detect memory issues and leaks. They are run as part of the Github workflow. + +The fuzzers use [LibFuzzer](https://llvm.org/docs/LibFuzzer.html). + +The targets can be run with the provided `Makefile` as follows: + +```bash +# Run the tests +make run_tests + +# Fuzz the pcapd daemon +make fuzz_pcap +``` diff --git a/app/src/main/jni/tests/fuzz/CMakeLists.txt b/app/src/main/jni/tests/fuzz/CMakeLists.txt new file mode 100644 index 00000000..67a22a34 --- /dev/null +++ b/app/src/main/jni/tests/fuzz/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(fuzz_pcapd fuzz_pcapd.c) +target_link_libraries(fuzz_pcapd libpcapd.so) diff --git a/app/src/main/jni/tests/fuzz_pcapd.c b/app/src/main/jni/tests/fuzz/fuzz_pcapd.c similarity index 100% rename from app/src/main/jni/tests/fuzz_pcapd.c rename to app/src/main/jni/tests/fuzz/fuzz_pcapd.c diff --git a/app/src/main/jni/tests/run_fuzz.sh b/app/src/main/jni/tests/run_fuzz.sh deleted file mode 100755 index fe5aee01..00000000 --- a/app/src/main/jni/tests/run_fuzz.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# To be run from the current directory (tests) - -mkdir -p build -( cd build && cmake .. -DFUZZING=1 && make -j$(nproc) fuzz_pcapd ) -( cd build && mkdir -p CORPUS && ./fuzz_pcapd CORPUS ../../../../../../submodules/nDPI/tests/pcap ../pcap >/dev/null ) diff --git a/app/src/main/jni/tests/run_tests.sh b/app/src/main/jni/tests/run_tests.sh deleted file mode 100755 index 0267b107..00000000 --- a/app/src/main/jni/tests/run_tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -# To be run from the current directory -mkdir -p build -cd build && cmake .. && make -j$(nproc) run_tests diff --git a/app/src/main/jni/tests/test/CMakeLists.txt b/app/src/main/jni/tests/test/CMakeLists.txt new file mode 100644 index 00000000..6c64e6c6 --- /dev/null +++ b/app/src/main/jni/tests/test/CMakeLists.txt @@ -0,0 +1,31 @@ +include(CTest) + +# Target to run tests and build them if necessary +add_custom_target(build_tests) +add_custom_target(run_tests COMMAND CTEST_OUTPUT_ON_FAILURE=1 ${CMAKE_CTEST_COMMAND}) +add_dependencies(run_tests build_tests) +include_directories(..) + +# test_source(target) +macro(test_source) + add_executable(${ARGV0} ${ARGV0}.c ../test_utils.c) + add_dependencies(${ARGV0} libpcapd.so) + add_dependencies(build_tests ${ARGV0}) + + target_link_libraries(${ARGV0} capture) +endmacro() + +# Tests +test_source(pcap_reader) + +test_source(dpi) +add_test(NAME dpi_extract COMMAND ./dpi extract) + +test_source(blacklist) +add_test(NAME blacklist_match COMMAND ./blacklist match) +add_test(NAME blacklist_detection COMMAND ./blacklist detection) + +test_source(dump_api) +add_test(NAME dump_api_snaplen COMMAND ./dump_api snaplen) +add_test(NAME dump_api_max_pkts_flow COMMAND ./dump_api max_pkts_per_flow) +add_test(NAME dump_api_max_size COMMAND ./dump_api max_dump_size) diff --git a/app/src/main/jni/tests/blacklist.c b/app/src/main/jni/tests/test/blacklist.c similarity index 100% rename from app/src/main/jni/tests/blacklist.c rename to app/src/main/jni/tests/test/blacklist.c diff --git a/app/src/main/jni/tests/dpi.c b/app/src/main/jni/tests/test/dpi.c similarity index 100% rename from app/src/main/jni/tests/dpi.c rename to app/src/main/jni/tests/test/dpi.c diff --git a/app/src/main/jni/tests/dump_api.c b/app/src/main/jni/tests/test/dump_api.c similarity index 100% rename from app/src/main/jni/tests/dump_api.c rename to app/src/main/jni/tests/test/dump_api.c diff --git a/app/src/main/jni/tests/pcap_reader.c b/app/src/main/jni/tests/test/pcap_reader.c similarity index 100% rename from app/src/main/jni/tests/pcap_reader.c rename to app/src/main/jni/tests/test/pcap_reader.c diff --git a/app/src/main/jni/tests/test_utils.c b/app/src/main/jni/tests/test_utils.c index 530b02e0..9bda5ac5 100644 --- a/app/src/main/jni/tests/test_utils.c +++ b/app/src/main/jni/tests/test_utils.c @@ -34,7 +34,7 @@ static u_char pcap_read_buf[65535]; /* ******************************************************* */ static void getPcapdPath(struct pcapdroid *pd, const char *prog_name, char *buf, int bufsize) { - snprintf(buf, bufsize, "main/pcapd/libpcapd.so"); + snprintf(buf, bufsize, "../main/pcapd/libpcapd.so"); } /* ******************************************************* */ diff --git a/app/src/main/jni/tests/test_utils.h b/app/src/main/jni/tests/test_utils.h index 2afae27c..4ec30e21 100644 --- a/app/src/main/jni/tests/test_utils.h +++ b/app/src/main/jni/tests/test_utils.h @@ -28,7 +28,7 @@ #define assert1(x) assert((x) == 1) #define assert_ip_equal(ipver, a, b) assert(zdtun_cmp_ip((ipver), (a), (b)) == 0) -#define PCAP_PATH "../pcap" +#define PCAP_PATH "../../pcap" #define PCAP_OUT_PATH "/tmp/test_out.pcap" void add_test(const char *name, void (*test_cb)()); diff --git a/docs/testing.md b/docs/testing.md index b3889039..e7e32182 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -6,9 +6,7 @@ Tests in PCAPdroid can be split in the following categories: to mock the Android API, allowing them to be run locally (without an Android device). - [Native tests](https://github.com/emanuele-f/PCAPdroid/tree/dev/app/src/main/jni/tests): - they can be run with `./run_tests.sh` on a linux host. They are built - with the [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) - to detect memory issues and leaks. + tests and fuzzing targets for native code. Check out their readme for more details. The tests are executed on every push via the [Github workflows](https://github.com/emanuele-f/PCAPdroid/tree/dev/.github/workflows).