diff mbox series

[OpenWrt-Devel,fwtool,5/8] add cram based unit tests

Message ID 20191023105339.16326-6-ynezz@true.cz
State Accepted
Delegated to: Petr Štetiar
Headers show
Series fwtool improvements | expand

Commit Message

Petr Štetiar Oct. 23, 2019, 10:53 a.m. UTC
For improved QA etc.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
---
 .gitignore                      |   3 ++
 .gitlab-ci.yml                  |  11 ++++
 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         |  12 +++++
 tests/cram/test_fwtool.t        |  90 ++++++++++++++++++++++++++++++++
 tests/test-crc32.c              |  26 +++++++++
 10 files changed, 175 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 mbox series

Patch

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..e13f3ab4edf7
--- /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 56180ce3c915..fc6559fbb1ca 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,14 @@ 
+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
+
+stages:
+  - pre-build
+  - test
+
+check shell scripts with shellcheck:
+  stage: pre-build
+  extends: .openwrt-shellcheck
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a73ce69f74c0..98ce26787d4c 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_SBINDIR})
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 000000000000..e07ce4daaea1
--- /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~<Z-*mJ_JyXDQH-=Au>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=$<l4;n!n}&GK-{vAV^(YRp;7*#en%CEZk`0{dF%;l+Kfl|t
zJ}@px)DlOMCTognqeVlSE1i|UHq2riYni%4jjh-2qM<ioR|;<jtXPg6@wSkJZqc7F
W`|Bv9Yy%syGZ6ZnVNbe0bo>wLPM;hA

literal 0
HcmV?d00001

diff --git a/tests/artifacts/metadata.json b/tests/artifacts/metadata.json
new file mode 100644
index 000000000000..0c32faee2607
--- /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 000000000000..abf7a4d7a13b
--- /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=$<TARGET_FILE:fwtool>")
+SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "TEST_CRC32=$<TARGET_FILE:test-crc32>")
diff --git a/tests/cram/test_crc32.t b/tests/cram/test_crc32.t
new file mode 100644
index 000000000000..ad50d0f54024
--- /dev/null
+++ b/tests/cram/test_crc32.t
@@ -0,0 +1,12 @@ 
+set PATH for convenience:
+
+  $ [ -n "$TEST_CRC32" ] && export PATH="$(dirname "$TEST_CRC32"):$PATH"
+
+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 000000000000..aeebbceb61a9
--- /dev/null
+++ b/tests/cram/test_fwtool.t
@@ -0,0 +1,90 @@ 
+set PATH and ARTIFACTS for convenience:
+
+  $ [ -n "$FWTOOL" ] && export PATH="$(dirname "$FWTOOL"):$PATH"
+  $ export ARTIFACTS="$TESTDIR/../artifacts"
+
+check usage:
+
+  $ fwtool
+  Usage: fwtool <options> <firmware>
+  
+  Options:
+    -S <file>:\t\tAppend signature file to firmware image (esc)
+    -I <file>:\t\tAppend metadata file to firmware image (esc)
+    -s <file>:\t\tExtract signature file from firmware image (esc)
+    -i <file>:\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 000000000000..2e0b06e4acc0
--- /dev/null
+++ b/tests/test-crc32.c
@@ -0,0 +1,26 @@ 
+#include <stdio.h>
+
+#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;
+}