Add basic cram based unit tests
authorPetr Štetiar <ynezz@true.cz>
Tue, 8 Dec 2020 11:29:59 +0000 (12:29 +0100)
committerPetr Štetiar <ynezz@true.cz>
Fri, 11 Dec 2020 10:17:22 +0000 (11:17 +0100)
For the start just basic uclient-fetch functionality coverage.

Signed-off-by: Petr Štetiar <ynezz@true.cz>
CMakeLists.txt
tests/CMakeLists.txt [new file with mode: 0644]
tests/cram/CMakeLists.txt [new file with mode: 0644]
tests/cram/server/lorem [new file with mode: 0644]
tests/cram/test-san_uclient-fetch.t [new file with mode: 0644]
tests/cram/test_uclient-fetch.t [new file with mode: 0644]

index 841bc0f..f0388ab 100644 (file)
@@ -16,12 +16,32 @@ ELSE(BUILD_STATIC)
   FIND_LIBRARY(ubox_library NAMES ubox)
 ENDIF(BUILD_STATIC)
 
-ADD_LIBRARY(uclient SHARED uclient.c uclient-http.c uclient-utils.c)
+SET(LIB_SOURCES uclient.c uclient-http.c uclient-utils.c)
+ADD_LIBRARY(uclient SHARED ${LIB_SOURCES})
 TARGET_LINK_LIBRARIES(uclient ${ubox_library} dl)
 
-ADD_EXECUTABLE(uclient-fetch uclient-fetch.c progress.c)
+SET(CLI_SOURCES uclient-fetch.c progress.c)
+ADD_EXECUTABLE(uclient-fetch ${CLI_SOURCES})
 TARGET_LINK_LIBRARIES(uclient-fetch uclient)
 
+IF(UNIT_TESTING)
+  ADD_DEFINITIONS(-DUNIT_TESTING)
+  ENABLE_TESTING()
+  ADD_SUBDIRECTORY(tests)
+
+  IF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+    ADD_LIBRARY(uclient-san SHARED ${LIB_SOURCES})
+    TARGET_COMPILE_OPTIONS(uclient-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all)
+    TARGET_LINK_OPTIONS(uclient-san PRIVATE -fsanitize=undefined,address,leak)
+    TARGET_LINK_LIBRARIES(uclient-san ${ubox_library} dl)
+
+    ADD_EXECUTABLE(uclient-fetch-san ${CLI_SOURCES})
+    TARGET_COMPILE_OPTIONS(uclient-fetch-san PRIVATE -g -fno-omit-frame-pointer -fsanitize=undefined,address,leak -fno-sanitize-recover=all)
+    TARGET_LINK_OPTIONS(uclient-fetch-san PRIVATE -fsanitize=undefined,address,leak)
+    TARGET_LINK_LIBRARIES(uclient-fetch-san uclient-san ${ubox_library} dl)
+  ENDIF()
+ENDIF()
+
 INSTALL(FILES uclient.h uclient-utils.h
        DESTINATION include/libubox
 )
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3d339b1
--- /dev/null
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(cram)
diff --git a/tests/cram/CMakeLists.txt b/tests/cram/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ba75802
--- /dev/null
@@ -0,0 +1,38 @@
+FIND_PACKAGE(PythonInterp 3 REQUIRED)
+FILE(GLOB test_cases "test_*.t")
+
+IF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+  FILE(GLOB test_cases_san "test-san_*.t")
+ENDIF()
+
+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_CUSTOM_TARGET(
+       http-server-kill ALL
+       COMMAND pkill --full -9 "${PYTHON_VENV_DIR}/bin/python3 -m http.server 1922 --bind 127.0.0.1" > /dev/null 2>&1 || true
+       DEPENDS ${PYTHON_VENV_CRAM}
+)
+
+ADD_CUSTOM_TARGET(
+       http-server ALL
+       COMMAND ${PYTHON_VENV_DIR}/bin/python3 -m http.server 1922 --bind 127.0.0.1 > /dev/null 2>&1 &
+       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/server
+       DEPENDS http-server-kill
+)
+
+ADD_TEST(
+       NAME cram
+       COMMAND ${PYTHON_VENV_CRAM} ${test_cases} ${test_cases_san}
+       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+SET_PROPERTY(TEST cram APPEND PROPERTY ENVIRONMENT "BUILD_BIN_DIR=$<TARGET_FILE_DIR:uclient-fetch>")
diff --git a/tests/cram/server/lorem b/tests/cram/server/lorem
new file mode 100644 (file)
index 0000000..133af11
--- /dev/null
@@ -0,0 +1,64 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas accumsan dui
+diam, sit amet vehicula nisl tincidunt non. Duis orci urna, luctus porttitor
+viverra non, interdum id erat. Vivamus in tortor eu augue dignissim imperdiet
+vitae ut ligula. Nunc luctus arcu viverra dolor commodo, et pellentesque
+lectus convallis. Donec molestie gravida venenatis. Curabitur vitae nulla at
+nisi ullamcorper sagittis vitae eget arcu. Sed elementum neque metus, in
+sollicitudin lorem vestibulum sed. Etiam non leo id eros ultrices hendrerit.
+
+Etiam sed luctus lacus. Fusce congue quam varius, cursus enim id, varius
+tellus. Suspendisse at mauris blandit, tempor urna non, pharetra tortor. In
+laoreet turpis a sollicitudin auctor. Duis semper diam mi, at mollis dolor
+tristique a. Sed sed mauris diam. Curabitur vel eleifend lorem. Quisque vel
+erat ac nulla vestibulum elementum. Curabitur euismod mauris lorem, at
+vestibulum justo accumsan eget. Proin pharetra scelerisque est, eget lobortis
+nulla. Ut sit amet tellus pellentesque, fermentum erat vitae, euismod risus.
+Vivamus sed nibh ut neque efficitur lacinia hendrerit accumsan leo.
+Suspendisse feugiat molestie suscipit.
+
+Sed mattis elit non nibh interdum, eu volutpat sem euismod. Nullam eu nibh id
+ligula semper molestie quis at nisi. Nulla vulputate, risus vitae vulputate
+dapibus, ligula erat volutpat dui, in condimentum tortor sapien et eros. Cras
+sed est consectetur, iaculis est a, ultricies felis. Phasellus dignissim neque
+quis urna aliquam, at consequat turpis rutrum. Ut gravida dolor nisi, et
+aliquam massa fermentum sit amet. In eu odio vel libero suscipit dignissim et
+ac justo. Morbi quis sollicitudin elit. Etiam varius vel odio ac dapibus. Sed
+ut lorem auctor, scelerisque lacus sit amet, ultrices lorem. Mauris dui
+mauris, sagittis id fermentum vitae, tincidunt vel sem. Morbi viverra erat
+nulla, et pharetra mauris condimentum maximus. Nam orci ex, semper nec rutrum
+sed, gravida lobortis nisl.
+
+Vivamus eleifend ligula leo, a sodales augue blandit eget. Sed varius molestie
+neque vel placerat. Nam volutpat sodales metus, et blandit ipsum vulputate et.
+Quisque eget quam sit amet nisl blandit varius in ac neque. Pellentesque
+habitant morbi tristique senectus et netus et malesuada fames ac turpis
+egestas. Donec ultricies mattis porta. Pellentesque in sollicitudin lacus.
+
+Duis quis dui consequat lacus ullamcorper pretium at eget justo. Mauris
+placerat dui vel augue rutrum luctus. Fusce mi purus, faucibus nec euismod sit
+amet, condimentum sed sem. Ut dictum arcu et eros volutpat, et gravida erat
+ultricies. Nam auctor, augue vitae cursus tempor, nisi lacus hendrerit massa,
+a varius mauris est sit amet sapien. Cras ac varius turpis. Ut vitae ligula
+neque. Cras nec felis ut orci accumsan maximus. Maecenas sed tempus magna.
+
+Sed metus risus, eleifend vitae viverra nec, volutpat vitae velit. Vivamus
+sodales porttitor urna, quis hendrerit est tempus nec. Mauris ligula ex,
+commodo vitae odio vel, volutpat lacinia libero. Nulla facilisis, ex sit amet
+rhoncus cursus, purus turpis condimentum mi, ac euismod tellus elit eu felis.
+Sed ultrices dolor pulvinar, laoreet lacus in, viverra arcu. Pellentesque a
+turpis felis. Morbi ornare nunc a hendrerit elementum.
+
+Sed laoreet dictum consequat. Maecenas et scelerisque justo, et vulputate
+diam. Vivamus nec erat quis nunc rutrum consectetur. Sed venenatis orci
+ligula, nec luctus massa tristique non. Etiam porta, nunc scelerisque bibendum
+tincidunt, mauris libero consequat odio, eu tempus neque augue eget massa.
+Nulla eu risus fermentum, ornare ipsum a, blandit nulla. Mauris in tempus
+quam, eu rutrum risus. Nunc maximus fringilla ante, et suscipit mi dictum
+laoreet. In sed ligula dictum, maximus neque ut, tincidunt mauris. Sed
+ultricies mauris in neque semper, eu congue nisl ullamcorper. Aliquam ac
+aliquam arcu.
+
+Nulla ante sapien, egestas at mattis vel, vehicula vitae urna. In tempus at
+nibh consequat scelerisque. Etiam interdum placerat erat ut finibus. Sed
+fermentum dignissim ligula, quis vehicula nulla faucibus aliquam. Cras elit
+lacus, porta ut vehicula eget orci aliquam.
diff --git a/tests/cram/test-san_uclient-fetch.t b/tests/cram/test-san_uclient-fetch.t
new file mode 100644 (file)
index 0000000..eee1de0
--- /dev/null
@@ -0,0 +1,88 @@
+check uclient-fetch usage:
+
+  $ [ -n "$BUILD_BIN_DIR" ] && export PATH="$BUILD_BIN_DIR:$PATH"
+  $ alias uc='uclient-fetch-san'
+
+  $ uc
+  Usage: uclient-fetch-san [options] <URL>
+  Options:
+  \t-4\t\t\t\tUse IPv4 only (esc)
+  \t-6\t\t\t\tUse IPv6 only (esc)
+  \t-q\t\t\t\tTurn off status messages (esc)
+  \t-O <file>\t\t\tRedirect output to file (use "-" for stdout) (esc)
+  \t-P <dir>\t\t\tSet directory for output files (esc)
+  \t--user=<user>\t\t\tHTTP authentication username (esc)
+  \t--password=<password>\t\tHTTP authentication password (esc)
+  \t--user-agent|-U <str>\t\tSet HTTP user agent (esc)
+  \t--post-data=STRING\t\tuse the POST method; send STRING as the data (esc)
+  \t--post-file=FILE\t\tuse the POST method; send FILE as the data (esc)
+  \t--spider|-s\t\t\tSpider mode - only check file existence (esc)
+  \t--timeout=N|-T N\t\tSet connect/request timeout to N seconds (esc)
+  \t--proxy=on|off|-Y on|off\tEnable/disable env var configured proxy (esc)
+  
+  HTTPS options:
+  \t--ca-certificate=<cert>\t\tLoad CA certificates from file <cert> (esc)
+  \t--no-check-certificate\t\tdon't validate the server's certificate (esc)
+  \t--ciphers=<cipherlist>\t\tSet the cipher list string (esc)
+  
+  [1]
+
+download lorem ipsum verbose:
+
+  $ uc -O lorem http://127.0.0.1:1922/lorem
+  Downloading 'http://127.0.0.1:1922/lorem'
+  Connecting to 127.0.0.1:1922
+  Writing to 'lorem'
+  \r (no-eol) (esc)
+  lorem                100% |*******************************|  4111   0:00:00 ETA
+  Download completed (4111 bytes)
+
+  $ md5sum lorem
+  887943f7c25bd6cec4570c405241b425  lorem
+
+download lorem ipsum quiet:
+
+  $ uc -q -O lorem http://127.0.0.1:1922/lorem
+
+  $ md5sum lorem
+  887943f7c25bd6cec4570c405241b425  lorem
+
+check that HTTP 404 errors are handled properly:
+
+  $ uc http://127.0.0.1:1922/does-not-exist
+  Downloading 'http://127.0.0.1:1922/does-not-exist'
+  Connecting to 127.0.0.1:1922
+  HTTP error 404
+  [8]
+
+  $ uc -q http://127.0.0.1:1922/does-not-exist
+  [8]
+
+check that SSL works:
+
+  $ uc -q -O /dev/null 'https://www.openwrt.org'
+
+  $ uc -O /dev/null 'https://downloads.openwrt.org/does-not-exist' 2>&1 | grep error
+  HTTP error 404
+
+check handling of certificate issues:
+
+  $ uc -O /dev/null 'https://self-signed.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc -O /dev/null 'https://untrusted-root.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc -O /dev/null 'https://expired.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc --ca-certificate=/dev/null -O /dev/null 'https://www.openwrt.org/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+check that certificate issues can be disabled:
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://self-signed.badssl.com/'
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://untrusted-root.badssl.com/'
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://expired.badssl.com/'
diff --git a/tests/cram/test_uclient-fetch.t b/tests/cram/test_uclient-fetch.t
new file mode 100644 (file)
index 0000000..3dd23ab
--- /dev/null
@@ -0,0 +1,88 @@
+check uclient-fetch usage:
+
+  $ [ -n "$BUILD_BIN_DIR" ] && export PATH="$BUILD_BIN_DIR:$PATH"
+  $ alias uc='valgrind --quiet --leak-check=full uclient-fetch'
+
+  $ uc
+  Usage: uclient-fetch [options] <URL>
+  Options:
+  \t-4\t\t\t\tUse IPv4 only (esc)
+  \t-6\t\t\t\tUse IPv6 only (esc)
+  \t-q\t\t\t\tTurn off status messages (esc)
+  \t-O <file>\t\t\tRedirect output to file (use "-" for stdout) (esc)
+  \t-P <dir>\t\t\tSet directory for output files (esc)
+  \t--user=<user>\t\t\tHTTP authentication username (esc)
+  \t--password=<password>\t\tHTTP authentication password (esc)
+  \t--user-agent|-U <str>\t\tSet HTTP user agent (esc)
+  \t--post-data=STRING\t\tuse the POST method; send STRING as the data (esc)
+  \t--post-file=FILE\t\tuse the POST method; send FILE as the data (esc)
+  \t--spider|-s\t\t\tSpider mode - only check file existence (esc)
+  \t--timeout=N|-T N\t\tSet connect/request timeout to N seconds (esc)
+  \t--proxy=on|off|-Y on|off\tEnable/disable env var configured proxy (esc)
+  
+  HTTPS options:
+  \t--ca-certificate=<cert>\t\tLoad CA certificates from file <cert> (esc)
+  \t--no-check-certificate\t\tdon't validate the server's certificate (esc)
+  \t--ciphers=<cipherlist>\t\tSet the cipher list string (esc)
+  
+  [1]
+
+download lorem ipsum verbose:
+
+  $ uc -O lorem http://127.0.0.1:1922/lorem
+  Downloading 'http://127.0.0.1:1922/lorem'
+  Connecting to 127.0.0.1:1922
+  Writing to 'lorem'
+  \r (no-eol) (esc)
+  lorem                100% |*******************************|  4111   0:00:00 ETA
+  Download completed (4111 bytes)
+
+  $ md5sum lorem
+  887943f7c25bd6cec4570c405241b425  lorem
+
+download lorem ipsum quiet:
+
+  $ uc -q -O lorem http://127.0.0.1:1922/lorem
+
+  $ md5sum lorem
+  887943f7c25bd6cec4570c405241b425  lorem
+
+check that HTTP 404 errors are handled properly:
+
+  $ uc http://127.0.0.1:1922/does-not-exist
+  Downloading 'http://127.0.0.1:1922/does-not-exist'
+  Connecting to 127.0.0.1:1922
+  HTTP error 404
+  [8]
+
+  $ uc -q http://127.0.0.1:1922/does-not-exist
+  [8]
+
+check that SSL works:
+
+  $ uc -q -O /dev/null 'https://www.openwrt.org'
+
+  $ uc -O /dev/null 'https://downloads.openwrt.org/does-not-exist' 2>&1 | grep error
+  HTTP error 404
+
+check handling of certificate issues:
+
+  $ uc -O /dev/null 'https://self-signed.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc -O /dev/null 'https://untrusted-root.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc -O /dev/null 'https://expired.badssl.com/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+  $ uc --ca-certificate=/dev/null -O /dev/null 'https://www.openwrt.org/' 2>&1 | grep error
+  Connection error: Invalid SSL certificate
+
+check that certificate issues can be disabled:
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://self-signed.badssl.com/'
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://untrusted-root.badssl.com/'
+
+  $ uc --no-check-certificate -q -O /dev/null 'https://expired.badssl.com/'