From e5666ed3b47c311f3373afe9748abdb1a5910ae6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petr=20=C5=A0tetiar?= Date: Thu, 17 Oct 2019 22:50:06 +0200 Subject: [PATCH] add cram based unit tests MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For improved QA etc. Signed-off-by: Petr Å tetiar --- .gitignore | 3 ++ .gitlab-ci.yml | 3 ++ CMakeLists.txt | 6 +++ tests/CMakeLists.txt | 4 ++ tests/artifacts/key-build.ucert | Bin 0 -> 516 bytes tests/artifacts/metadata.json | 1 + tests/cram/CMakeLists.txt | 22 ++++++++ tests/cram/test_crc32.t | 13 +++++ tests/cram/test_fwtool.t | 91 ++++++++++++++++++++++++++++++++ tests/test-crc32.c | 26 +++++++++ 10 files changed, 169 insertions(+) create mode 100644 .gitignore create mode 100644 tests/CMakeLists.txt create mode 100644 tests/artifacts/key-build.ucert create mode 100644 tests/artifacts/metadata.json create mode 100644 tests/cram/CMakeLists.txt create mode 100644 tests/cram/test_crc32.t create mode 100644 tests/cram/test_fwtool.t create mode 100644 tests/test-crc32.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e13f3ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +tests/cram/*.t.err +*.pyc +.venv diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56180ce..a699528 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,6 @@ +variables: + CI_ENABLE_UNIT_TESTING: 1 + include: - remote: https://gitlab.com/ynezz/openwrt-ci/raw/master/openwrt-ci/gitlab/main.yml - remote: https://gitlab.com/ynezz/openwrt-ci/raw/master/openwrt-ci/gitlab/pipeline.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c449f9..dfe6045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,10 @@ INCLUDE(GNUInstallDirs) ADD_DEFINITIONS(-Wall -Werror -Wextra -Wno-unused-parameter) ADD_EXECUTABLE(fwtool fwtool.c) + +IF(UNIT_TESTING) + ENABLE_TESTING() + ADD_SUBDIRECTORY(tests) +ENDIF() + INSTALL(TARGETS fwtool RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..e07ce4d --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +ADD_SUBDIRECTORY(cram) + +ADD_EXECUTABLE(test-crc32 test-crc32.c) +TARGET_INCLUDE_DIRECTORIES(test-crc32 PRIVATE ${PROJECT_SOURCE_DIR}) diff --git a/tests/artifacts/key-build.ucert b/tests/artifacts/key-build.ucert new file mode 100644 index 0000000000000000000000000000000000000000..7228f110a2d44137a9c0289b5f9a1add0d1f0623 GIT binary patch literal 516 zcmbu5J#(T^6o!vQb`t9pDd|&4Py{oRLNxdh5TmHbOeS-=T*EgA7nGFQ^;c|@ndFD0 z*k7@~X4UO7=~A6@p5{Hz3sA8E;CCL;G|wop861ZpiRd+xxlhslwo1k)C39tSEJj=% z3$13oCGyqD;@%#pvA5-yyfYhVck7~A5FKTnD0>AjGaCQ>{8 zrdR7aR@z!@Vh%-eoARtypV3A#4YH}>JEFQ-A$?eTVsENY0r>L*@Bt?|CMks-z&V^A zR$3-x|2aVA7r+Ia6)14+RT_s!`0$>X|2f$vZb~vlkNk1>_V*`12tShC+It<~7w$@o zQNUQa8`uZ?PqLSsVo=$wLPM;hA literal 0 HcmV?d00001 diff --git a/tests/artifacts/metadata.json b/tests/artifacts/metadata.json new file mode 100644 index 0000000..0c32fae --- /dev/null +++ b/tests/artifacts/metadata.json @@ -0,0 +1 @@ +{ "metadata_version": "1.0", "supported_devices":["tplink,archer-c7-v5","archer-c7-v5"], "version": { "dist": "OpenWrt", "version": "SNAPSHOT", "revision": "r11215+4-bba6646b5cba", "target": "ath79/generic", "board": "tplink_archer-c7-v5" } } diff --git a/tests/cram/CMakeLists.txt b/tests/cram/CMakeLists.txt new file mode 100644 index 0000000..abf7a4d --- /dev/null +++ b/tests/cram/CMakeLists.txt @@ -0,0 +1,22 @@ +FIND_PACKAGE(PythonInterp 3 REQUIRED) +FILE(GLOB test_cases "test_*.t") + +SET(PYTHON_VENV_DIR "${CMAKE_CURRENT_BINARY_DIR}/.venv") +SET(PYTHON_VENV_PIP "${PYTHON_VENV_DIR}/bin/pip") +SET(PYTHON_VENV_CRAM "${PYTHON_VENV_DIR}/bin/cram") + +ADD_CUSTOM_COMMAND( + OUTPUT ${PYTHON_VENV_CRAM} + COMMAND ${PYTHON_EXECUTABLE} -m venv ${PYTHON_VENV_DIR} + COMMAND ${PYTHON_VENV_PIP} install cram +) +ADD_CUSTOM_TARGET(prepare-cram-venv ALL DEPENDS ${PYTHON_VENV_CRAM}) + +ADD_TEST( + NAME cram + COMMAND ${PYTHON_VENV_CRAM} ${test_cases} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "FWTOOL=$") +SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "TEST_CRC32=$") diff --git a/tests/cram/test_crc32.t b/tests/cram/test_crc32.t new file mode 100644 index 0000000..9102336 --- /dev/null +++ b/tests/cram/test_crc32.t @@ -0,0 +1,13 @@ +set PATH for convenience: + + $ [ -n "$TEST_CRC32" ] && export PATH="$(dirname "$TEST_CRC32"):$PATH" + $ alias test-crc32='valgrind --quiet --leak-check=full test-crc32' + +check that crc32 is producing expected results: + + $ test-crc32 + all_ffs=0x44f33105 + all_7fs=0x3726dda7 + all_ones=0xbea1dbe8 + all_zeroes=0xa77a69f2 + quick_fox=0x7c7180f2 diff --git a/tests/cram/test_fwtool.t b/tests/cram/test_fwtool.t new file mode 100644 index 0000000..530cf3d --- /dev/null +++ b/tests/cram/test_fwtool.t @@ -0,0 +1,91 @@ +set PATH and ARTIFACTS for convenience: + + $ [ -n "$FWTOOL" ] && export PATH="$(dirname "$FWTOOL"):$PATH" + $ export ARTIFACTS="$TESTDIR/../artifacts" + $ alias fwtool='valgrind --quiet --leak-check=full fwtool' + +check usage: + + $ fwtool + Usage: fwtool + + Options: + -S :\t\tAppend signature file to firmware image (esc) + -I :\t\tAppend metadata file to firmware image (esc) + -s :\t\tExtract signature file from firmware image (esc) + -i :\t\tExtract metadata file from firmware image (esc) + -t:\t\t\tRemove extracted chunks from firmare image (using -s, -i) (esc) + -T:\t\t\tOutput firmware image without extracted chunks to stdout (using -s, -i) (esc) + -q:\t\t\tQuiet (suppress error messages) (esc) + + [1] + +check that -T don't truncate ouput by 16 bytes and produces desired error output: + + $ dd if=/dev/urandom of=image.bin bs=512k count=1 2> /dev/null + $ cp image.bin image.bin.stripped + $ md5sum image.bin* > md5sums + + $ fwtool -T -i /dev/null image.bin > image.bin.stripped + Data not found + [1] + + $ md5sum --check md5sums + image.bin: OK + image.bin.stripped: OK + +check metadata insertion and extraction: + + $ cp "$ARTIFACTS/metadata.json" . + $ dd if=/dev/urandom of=image.bin bs=512k count=1 2> /dev/null + $ md5sum image.bin metadata.json > md5sums + + $ fwtool -I metadata.json image.bin + $ strings image.bin | grep metadata_version > metadata.json.extracted + $ diff --unified "$ARTIFACTS/metadata.json" metadata.json.extracted + $ rm metadata.json + + $ fwtool -t -i metadata.json image.bin + $ md5sum --check md5sums + image.bin: OK + metadata.json: OK + +check signature insertion and extraction: + + $ cp "$ARTIFACTS/key-build.ucert" . + $ dd if=/dev/urandom of=image.bin bs=512k count=1 2> /dev/null + $ md5sum image.bin key-build.ucert > md5sums + + $ fwtool -S key-build.ucert image.bin + $ tail --bytes 532 image.bin | head --bytes 516 > key-build.ucert.extracted + $ cmp --print-bytes "$ARTIFACTS/key-build.ucert" key-build.ucert.extracted + $ rm key-build.ucert + + $ fwtool -t -s key-build.ucert image.bin + $ md5sum --check md5sums + image.bin: OK + key-build.ucert: OK + +check both signature and metadata insertion and extraction: + + $ cp "$ARTIFACTS/metadata.json" "$ARTIFACTS/key-build.ucert" . + $ dd if=/dev/urandom of=image.bin bs=512k count=1 2> /dev/null + $ md5sum image.bin metadata.json key-build.ucert > md5sums + + $ fwtool -I metadata.json image.bin + $ fwtool -S key-build.ucert image.bin + + $ strings image.bin | grep metadata_version > metadata.json.extracted + $ diff -u "$ARTIFACTS/metadata.json" metadata.json.extracted + $ rm metadata.json + + $ tail --bytes 532 image.bin | head --bytes 516 > key-build.ucert.extracted + $ cmp -b "$ARTIFACTS/key-build.ucert" key-build.ucert.extracted + $ rm key-build.ucert + + $ fwtool -t -s key-build.ucert image.bin + $ fwtool -t -i metadata.json image.bin + $ md5sum --check md5sums + image.bin: OK + metadata.json: OK + key-build.ucert: OK diff --git a/tests/test-crc32.c b/tests/test-crc32.c new file mode 100644 index 0000000..2e0b06e --- /dev/null +++ b/tests/test-crc32.c @@ -0,0 +1,26 @@ +#include + +#include "crc32.h" +#include "utils.h" + +static uint32_t crc_table[256]; + +int main() +{ + uint32_t crc32 = ~0; + uint8_t all_ones[1<<10] = { 1 }; + uint8_t all_ffs[1<<5] = { 0xff }; + uint8_t all_7fs[1<<15] = { 0x7f }; + uint8_t all_zeroes[1<<8] = { 0 }; + uint8_t quick_fox[] = "The quick brown fox jumps over the lazy dog and then walks away."; + + crc32_filltable(crc_table); + + fprintf(stdout, "all_ffs=0x%x\n", cpu_to_be32(crc32_block(crc32, all_ffs, sizeof(all_ffs), crc_table))); + fprintf(stdout, "all_7fs=0x%x\n", cpu_to_be32(crc32_block(crc32, all_7fs, sizeof(all_7fs), crc_table))); + fprintf(stdout, "all_ones=0x%x\n", cpu_to_be32(crc32_block(crc32, all_ones, sizeof(all_ones), crc_table))); + fprintf(stdout, "all_zeroes=0x%x\n", cpu_to_be32(crc32_block(crc32, all_zeroes, sizeof(all_zeroes), crc_table))); + fprintf(stdout, "quick_fox=0x%x\n", cpu_to_be32(crc32_block(crc32, quick_fox, sizeof(quick_fox), crc_table))); + + return 0; +} -- 2.30.2