]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Implement unit testing using Google Test framework.
authorNathan Moinvaziri <nathan@nathanm.com>
Sun, 6 Feb 2022 17:52:27 +0000 (09:52 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sun, 13 Mar 2022 06:41:12 +0000 (07:41 +0100)
30 files changed:
.gitignore
CMakeLists.txt
Makefile.in
test/CMakeLists.txt [new file with mode: 0644]
test/Makefile.in
test/test_adler32.cc [moved from test/test_adler32.c with 66% similarity]
test/test_compress.cc [new file with mode: 0644]
test/test_crc32.c [deleted file]
test/test_crc32.cc [new file with mode: 0644]
test/test_deflate_bound.cc [new file with mode: 0644]
test/test_deflate_copy.cc [new file with mode: 0644]
test/test_deflate_dict.cc [new file with mode: 0644]
test/test_deflate_hash_head_0.cc [new file with mode: 0644]
test/test_deflate_header.cc [new file with mode: 0644]
test/test_deflate_params.cc [new file with mode: 0644]
test/test_deflate_pending.cc [new file with mode: 0644]
test/test_deflate_prime.cc [new file with mode: 0644]
test/test_deflate_quick_bi_valid.cc [moved from test/test_deflate_quick_bi_valid.c with 84% similarity]
test/test_deflate_quick_block_open.cc [moved from test/test_deflate_quick_block_open.c with 71% similarity]
test/test_deflate_tune.cc [new file with mode: 0644]
test/test_dict.cc [new file with mode: 0644]
test/test_gzio.cc [new file with mode: 0644]
test/test_hash_head_0.c [deleted file]
test/test_inflate_adler32.cc [moved from test/test_inflate_adler32.c with 52% similarity]
test/test_inflate_sync.cc [new file with mode: 0644]
test/test_large_buffers.cc [new file with mode: 0644]
test/test_main.cc [new file with mode: 0644]
test/test_shared.h [new file with mode: 0644]
test/test_small_buffers.cc [new file with mode: 0644]
test/test_version.cc [new file with mode: 0644]

index ff0a5909579b2758c01ed244f3628728afa2e4eb..239171c2d6349d04ab89fff932c9864e971e1e83 100644 (file)
 *.gcno
 *.gcov
 
-/test_adler32
-/test_crc32
+/benchmark_zlib
 /example
 /example64
 /examplesh
+/gtest_zlib
 /libz.so*
 /libz-ng.so*
 /makefixed
index 9b68cc60da31fe032b4b12c62f8a4402f7ff6bf4..d88ca32e8d93c5ebe5de0918da29990cb0db381a 100644 (file)
@@ -1165,6 +1165,12 @@ endif()
 option(ZLIB_ENABLE_TESTS "Build test binaries" ON)
 if(ZLIB_ENABLE_TESTS)
     enable_testing()
+
+    add_subdirectory(test)
+    if(WITH_BENCHMARKS)
+        add_subdirectory(test/benchmarks)
+    endif()
+
     macro(configure_test_executable target)
         target_include_directories(${target} PUBLIC
             "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
@@ -1188,15 +1194,6 @@ if(ZLIB_ENABLE_TESTS)
         add_test(NAME ${target} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:${target}>)
     endmacro()
 
-    file(GLOB TEST_SRCS
-        LIST_DIRECTORIES false
-        RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/test
-        ${CMAKE_CURRENT_SOURCE_DIR}/test/test_*.c)
-
-    foreach(TEST_SRC ${TEST_SRCS})
-        get_filename_component(TEST_NAME ${TEST_SRC} NAME_WE)
-        add_simple_test_executable(${TEST_NAME})
-    endforeach()
 
     if(NOT WIN32 AND ZLIB_COMPAT)
         add_simple_test_executable(CVE-2003-0107)
@@ -1303,10 +1300,6 @@ if(ZLIB_ENABLE_TESTS)
         endforeach()
     endif()
 
-    if(WITH_BENCHMARKS)
-        add_subdirectory(test/benchmarks)
-    endif()
-
     macro(test_minigzip name path)
         # Construct compression arguments for minigzip
         set(compress_args -k -c)
index e7ad5a65063f3a135bc1233dfc916c2a3d7ca3fa..2b8269099b6bb8072726ad54aac2149d2576af83 100644 (file)
@@ -154,7 +154,7 @@ PIC_OBJS = $(PIC_OBJC)
 
 all: static shared
 
-static: test_adler32$(EXE) test_crc32$(EXE) example$(EXE) minigzip$(EXE) fuzzers makefixed$(EXE) maketrees$(EXE) makecrct$(EXE)
+static: example$(EXE) minigzip$(EXE) fuzzers makefixed$(EXE) maketrees$(EXE) makecrct$(EXE)
 
 shared: examplesh$(EXE) minigzipsh$(EXE)
 
@@ -263,12 +263,6 @@ maketrees.o:
 makecrct.o:
        $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makecrct.c
 
-test_adler32.o:
-       $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/test_adler32.c
-
-test_crc32.o:
-       $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/test_crc32.c
-
 zlibrc.o: win32/zlib$(SUFFIX)1.rc
        $(RC) $(RCFLAGS) -o $@ win32/zlib$(SUFFIX)1.rc
 
@@ -323,17 +317,12 @@ ifneq ($(STRIP),)
        $(STRIP) $@
 endif
 
-test_adler32$(EXE): test_adler32.o $(OBJG) $(STATICLIB)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ test_adler32.o $(OBJG) $(TEST_LIBS) $(LDSHAREDLIBC)
+minigzipsh$(EXE): minigzip.o $(OBJG) $(SHAREDTARGET)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(OBJG) $(SHAREDTARGET) $(LDSHAREDLIBC)
 ifneq ($(STRIP),)
        $(STRIP) $@
 endif
 
-test_crc32$(EXE): test_crc32.o $(STATICLIB)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ test_crc32.o $(TEST_LIBS) $(LDSHAREDLIBC)
-ifneq ($(STRIP),)
-       $(STRIP) $@
-endif
 
 examplesh$(EXE): example.o $(PIC_TESTOBJG) $(SHAREDTARGET)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(PIC_TESTOBJG) $(SHAREDTARGET) $(LDSHAREDLIBC)
@@ -341,12 +330,6 @@ ifneq ($(STRIP),)
        $(STRIP) $@
 endif
 
-minigzipsh$(EXE): minigzip.o $(PIC_TESTOBJG) $(SHAREDTARGET)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(PIC_TESTOBJG) $(SHAREDTARGET) $(LDSHAREDLIBC)
-ifneq ($(STRIP),)
-       $(STRIP) $@
-endif
-
 makefixed$(EXE): makefixed.o $(OBJG) $(STATICLIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makefixed.o $(OBJG) $(TEST_LIBS) $(LDSHAREDLIBC)
 ifneq ($(STRIP),)
@@ -427,10 +410,7 @@ clean:
        @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) clean; fi
        @if [ -f test/Makefile ]; then $(MAKE) -C test clean; fi
        rm -f *.o *.lo *~ \
-          test_adler32$(EXE) test_crc32$(EXE) example$(EXE) minigzip$(EXE) \
-          examplesh$(EXE) minigzipsh$(EXE) \
-          fuzzer_checksum$(EXE) fuzzer_compress$(EXE) fuzzer_example_small$(EXE) fuzzer_example_large$(EXE) \
-          fuzzer_example_flush$(EXE) fuzzer_example_dict$(EXE) fuzzer_minigzip$(EXE) \
+          example$(EXE) minigzip$(EXE) minigzipsh$(EXE) fuzzer_*$(EXE) \
           infcover makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) \
           $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \
           foo.gz so_locations \
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..973e9f9
--- /dev/null
@@ -0,0 +1,44 @@
+cmake_minimum_required(VERSION 3.12)
+
+include(FetchContent)
+
+enable_language(CXX)
+
+# Google test requires at least C++11
+set(CMAKE_CXX_STANDARD 11)
+
+# Prevent overriding the parent project's compiler/linker settings for Windows
+set(gtest_force_shared_crt ON CACHE BOOL
+    "Use shared (DLL) run-time lib even when Google Test is built as static lib." FORCE)
+# Disable pthreads for simplicity
+set(gtest_disable_pthreads ON CACHE BOOL
+    "Disable uses of pthreads in gtest." FORCE)
+
+# Fetch Google test source code from official repository
+FetchContent_Declare(googletest
+    GIT_REPOSITORY https://github.com/google/googletest.git
+    GIT_TAG main)
+
+FetchContent_GetProperties(googletest)
+if(NOT googletest_POPULATED)
+    FetchContent_Populate(googletest)
+    add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
+endif()
+
+file(GLOB TEST_SRCS
+    LIST_DIRECTORIES false
+    RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/test_*.cc)
+
+add_executable(gtest_zlib ${TEST_SRCS})
+
+target_include_directories(gtest_zlib PRIVATE
+    ${CMAKE_SOURCE_DIR}
+    ${CMAKE_BINARY_DIR})
+
+target_link_libraries(gtest_zlib zlibstatic gtest)
+
+if(ZLIB_ENABLE_TESTS)
+    add_test(NAME gtest_zlib
+        COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:gtest_zlib>)
+endif()
index a32d0adf8d7ad087d6c4049e630334dc3828d2bc..de72edc0f45f77b1e8e5515dee31c41ab40bdbba 100644 (file)
@@ -48,7 +48,7 @@ endif
 teststatic: check_cross_dep
        @TMPST=tmpst_$$$$; \
        HELLOST=tmphellost_$$$$; \
-       if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${QEMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${QEMU_RUN} ../example$(EXE) $$TMPST && ${QEMU_RUN} ../test_adler32$(EXE) && ${QEMU_RUN} ../test_crc32$(EXE); then \
+       if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${QEMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${QEMU_RUN} ../example$(EXE) $$TMPST; then \
          echo '                *** zlib test OK ***'; \
        else \
          echo '                *** zlib test FAILED ***'; exit 1; \
similarity index 66%
rename from test/test_adler32.c
rename to test/test_adler32.cc
index 56e8c0ca1133ff3ec27180950ca8bc9a917c616d..fa113da5aeade2ceb23f43ea3243c315b72143f9 100644 (file)
@@ -4,32 +4,24 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-#  include "zlib.h"
-#else
-#  include "zlib-ng.h"
-#endif
-
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" {
+#  include "zbuild.h"
+#  include "cpu_features.h"
+}
+
+#include <gtest/gtest.h>
 
 typedef struct {
-    uint32_t line;
     uint32_t adler;
     const uint8_t *buf;
     uint32_t len;
     uint32_t expect;
 } adler32_test;
 
-void test_adler32(uint32_t adler, const uint8_t *buf, uint32_t len, uint32_t chk, uint32_t line) {
-    uint32_t res = PREFIX(adler32)(adler, buf, len);
-    if (res != chk) {
-        fprintf(stderr, "FAIL [%d]: adler32 returned 0x%08X expected 0x%08X\n",
-                line, res, chk);
-        exit(1);
-    }
-}
-
 static const uint8_t long_string[5552] = {
     'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q',
     'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k',
@@ -207,157 +199,191 @@ static const uint8_t long_string[5552] = {
     'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'};
 
 static const adler32_test tests[] = {
-   {__LINE__, 0x1, (const uint8_t *)0x0, 0, 0x1},
-   {__LINE__, 0x1, (const uint8_t *)"", 1, 0x10001},
-   {__LINE__, 0x1, (const uint8_t *)"a", 1, 0x620062},
-   {__LINE__, 0x1, (const uint8_t *)"abacus", 6, 0x8400270},
-   {__LINE__, 0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4},
-   {__LINE__, 0x1, (const uint8_t *)"campfire", 8, 0xea10348},
-   {__LINE__, 0x1, (const uint8_t *)"delta", 5, 0x61a020b},
-   {__LINE__, 0x1, (const uint8_t *)"executable", 10, 0x16fa0423},
-   {__LINE__, 0x1, (const uint8_t *)"file", 4, 0x41401a1},
-   {__LINE__, 0x1, (const uint8_t *)"greatest", 8, 0xefa0360},
-   {__LINE__, 0x1, (const uint8_t *)"inverter", 8, 0xf6f0370},
-   {__LINE__, 0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286},
-   {__LINE__, 0x1, (const uint8_t *)"karate", 6, 0x8a50279},
-   {__LINE__, 0x1, (const uint8_t *)"landscape", 9, 0x126a03ac},
-   {__LINE__, 0x1, (const uint8_t *)"machine", 7, 0xb5302d6},
-   {__LINE__, 0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca},
-   {__LINE__, 0x1, (const uint8_t *)"oblivion", 8, 0xf220363},
-   {__LINE__, 0x1, (const uint8_t *)"panama", 6, 0x8a1026f},
-   {__LINE__, 0x1, (const uint8_t *)"quest", 5, 0x6970233},
-   {__LINE__, 0x1, (const uint8_t *)"resource", 8, 0xf8d0369},
-   {__LINE__, 0x1, (const uint8_t *)"secret", 6, 0x8d10287},
-   {__LINE__, 0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366},
-   {__LINE__, 0x1, (const uint8_t *)"vector", 6, 0x8fb0294},
-   {__LINE__, 0x1, (const uint8_t *)"walrus", 6, 0x918029f},
-   {__LINE__, 0x1, (const uint8_t *)"xeno", 4, 0x45e01bb},
-   {__LINE__, 0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5},
-   {__LINE__, 0x1, (const uint8_t *)"zero", 4, 0x46e01c1},
-   {__LINE__, 0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d},
-   {__LINE__, 0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f},
-   {__LINE__, 0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e},
-   {__LINE__, 0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650},
-   {__LINE__, 0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690},
-   {__LINE__, 0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609},
-   {__LINE__, 0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703},
-   {__LINE__, 0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7},
-   {__LINE__, 0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698},
-   {__LINE__, 0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6},
-   {__LINE__, 0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c},
-   {__LINE__, 0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9},
-   {__LINE__, 0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769},
-   {__LINE__, 0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5},
-   {__LINE__, 0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750},
-   {__LINE__, 0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414},
-   {__LINE__, 0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405},
-   {__LINE__, 0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423},
-   {__LINE__, 0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421},
-   {__LINE__, 0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b},
-   {__LINE__, 0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d},
-   {__LINE__, 0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a},
-   {__LINE__, 0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d},
-   {__LINE__, 0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417},
-   {__LINE__, 0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412},
-   {__LINE__, 0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420},
-   {__LINE__, 0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419},
-   {__LINE__, 0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f},
-   {__LINE__, 0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f},
-   {__LINE__, 0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417},
-   {__LINE__, 0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841},
-   {__LINE__, 0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751},
-   {__LINE__, 0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a},
-   {__LINE__, 0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815},
-   {__LINE__, 0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661},
-   {__LINE__, 0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3},
-   {__LINE__, 0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb},
-   {__LINE__, 0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680},
-   {__LINE__, 0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f},
-   {__LINE__, 0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee},
-   {__LINE__, 0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92},
-   {__LINE__, 0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96},
-   {__LINE__, 0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8},
-   {__LINE__, 0x1, (const uint8_t *)long_string, 5552, 0x8b81718f},
-   {__LINE__, 0x7a30360d, (const uint8_t *)0x0, 0, 0x1},
-   {__LINE__, 0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee},
-   {__LINE__, 0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea},
-   {__LINE__, 0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da},
-   {__LINE__, 0xdc712e2,  (const uint8_t *)"backlog", 7, 0x9d0d15b5},
-   {__LINE__, 0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44},
-   {__LINE__, 0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521},
-   {__LINE__, 0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2},
-   {__LINE__, 0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a},
-   {__LINE__, 0xab058a2,  (const uint8_t *)"greatest", 8, 0xded05c01},
-   {__LINE__, 0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9},
-   {__LINE__, 0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4},
-   {__LINE__, 0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d},
-   {__LINE__, 0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024},
-   {__LINE__, 0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b},
-   {__LINE__, 0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb},
-   {__LINE__, 0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb},
-   {__LINE__, 0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f},
-   {__LINE__, 0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92},
-   {__LINE__, 0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5},
-   {__LINE__, 0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390},
-   {__LINE__, 0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39},
-   {__LINE__, 0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c},
-   {__LINE__, 0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516},
-   {__LINE__, 0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b},
-   {__LINE__, 0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4},
-   {__LINE__, 0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00},
-   {__LINE__, 0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b},
-   {__LINE__, 0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8},
-   {__LINE__, 0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c},
-   {__LINE__, 0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f},
-   {__LINE__, 0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f},
-   {__LINE__, 0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd},
-   {__LINE__, 0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446},
-   {__LINE__, 0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148},
-   {__LINE__, 0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc},
-   {__LINE__, 0x3275b9f,  (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284},
-   {__LINE__, 0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706},
-   {__LINE__, 0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a},
-   {__LINE__, 0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db},
-   {__LINE__, 0xe75b214,  (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8},
-   {__LINE__, 0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd},
-   {__LINE__, 0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4},
-   {__LINE__, 0x54b8e14,  (const uint8_t *)"42015093765128581010", 20, 0x49c19218},
-   {__LINE__, 0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38},
-   {__LINE__, 0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8},
-   {__LINE__, 0xbe92385,  (const uint8_t *)"49769333513942933689", 20, 0xfe1827af},
-   {__LINE__, 0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c},
-   {__LINE__, 0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda},
-   {__LINE__, 0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006},
-   {__LINE__, 0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c},
-   {__LINE__, 0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4},
-   {__LINE__, 0x75770fc,  (const uint8_t *)"29977409200786225655", 20, 0x707751b},
-   {__LINE__, 0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3},
-   {__LINE__, 0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3},
-   {__LINE__, 0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a},
-   {__LINE__, 0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0},
-   {__LINE__, 0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8},
-   {__LINE__, 0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8},
-   {__LINE__, 0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54},
-   {__LINE__, 0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e},
-   {__LINE__, 0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c},
-   {__LINE__, 0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c},
-   {__LINE__, 0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9},
-   {__LINE__, 0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652},
-   {__LINE__, 0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e},
-   {__LINE__, 0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664},
-   {__LINE__, 0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911},
-   {__LINE__, 0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73},
-   {__LINE__, 0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8},
-   {__LINE__, 0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2},
+   {0x1, (const uint8_t *)0x0, 0, 0x1},
+   {0x1, (const uint8_t *)"", 1, 0x10001},
+   {0x1, (const uint8_t *)"a", 1, 0x620062},
+   {0x1, (const uint8_t *)"abacus", 6, 0x8400270},
+   {0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4},
+   {0x1, (const uint8_t *)"campfire", 8, 0xea10348},
+   {0x1, (const uint8_t *)"delta", 5, 0x61a020b},
+   {0x1, (const uint8_t *)"executable", 10, 0x16fa0423},
+   {0x1, (const uint8_t *)"file", 4, 0x41401a1},
+   {0x1, (const uint8_t *)"greatest", 8, 0xefa0360},
+   {0x1, (const uint8_t *)"inverter", 8, 0xf6f0370},
+   {0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286},
+   {0x1, (const uint8_t *)"karate", 6, 0x8a50279},
+   {0x1, (const uint8_t *)"landscape", 9, 0x126a03ac},
+   {0x1, (const uint8_t *)"machine", 7, 0xb5302d6},
+   {0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca},
+   {0x1, (const uint8_t *)"oblivion", 8, 0xf220363},
+   {0x1, (const uint8_t *)"panama", 6, 0x8a1026f},
+   {0x1, (const uint8_t *)"quest", 5, 0x6970233},
+   {0x1, (const uint8_t *)"resource", 8, 0xf8d0369},
+   {0x1, (const uint8_t *)"secret", 6, 0x8d10287},
+   {0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366},
+   {0x1, (const uint8_t *)"vector", 6, 0x8fb0294},
+   {0x1, (const uint8_t *)"walrus", 6, 0x918029f},
+   {0x1, (const uint8_t *)"xeno", 4, 0x45e01bb},
+   {0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5},
+   {0x1, (const uint8_t *)"zero", 4, 0x46e01c1},
+   {0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d},
+   {0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f},
+   {0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e},
+   {0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650},
+   {0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690},
+   {0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609},
+   {0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703},
+   {0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7},
+   {0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698},
+   {0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6},
+   {0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c},
+   {0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9},
+   {0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769},
+   {0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5},
+   {0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750},
+   {0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414},
+   {0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405},
+   {0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423},
+   {0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421},
+   {0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b},
+   {0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d},
+   {0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a},
+   {0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d},
+   {0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417},
+   {0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412},
+   {0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420},
+   {0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419},
+   {0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f},
+   {0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f},
+   {0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417},
+   {0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841},
+   {0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751},
+   {0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a},
+   {0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815},
+   {0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661},
+   {0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3},
+   {0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb},
+   {0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680},
+   {0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f},
+   {0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee},
+   {0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92},
+   {0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96},
+   {0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8},
+   {0x1, (const uint8_t *)long_string, 5552, 0x8b81718f},
+   {0x7a30360d, (const uint8_t *)0x0, 0, 0x1},
+   {0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee},
+   {0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea},
+   {0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da},
+   {0xdc712e2,  (const uint8_t *)"backlog", 7, 0x9d0d15b5},
+   {0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44},
+   {0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521},
+   {0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2},
+   {0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a},
+   {0xab058a2,  (const uint8_t *)"greatest", 8, 0xded05c01},
+   {0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9},
+   {0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4},
+   {0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d},
+   {0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024},
+   {0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b},
+   {0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb},
+   {0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb},
+   {0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f},
+   {0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92},
+   {0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5},
+   {0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390},
+   {0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39},
+   {0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c},
+   {0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516},
+   {0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b},
+   {0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4},
+   {0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00},
+   {0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b},
+   {0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8},
+   {0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c},
+   {0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f},
+   {0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f},
+   {0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd},
+   {0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446},
+   {0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148},
+   {0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc},
+   {0x3275b9f,  (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284},
+   {0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706},
+   {0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a},
+   {0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db},
+   {0xe75b214,  (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8},
+   {0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd},
+   {0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4},
+   {0x54b8e14,  (const uint8_t *)"42015093765128581010", 20, 0x49c19218},
+   {0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38},
+   {0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8},
+   {0xbe92385,  (const uint8_t *)"49769333513942933689", 20, 0xfe1827af},
+   {0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c},
+   {0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda},
+   {0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006},
+   {0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c},
+   {0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4},
+   {0x75770fc,  (const uint8_t *)"29977409200786225655", 20, 0x707751b},
+   {0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3},
+   {0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3},
+   {0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a},
+   {0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0},
+   {0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8},
+   {0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8},
+   {0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54},
+   {0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e},
+   {0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c},
+   {0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c},
+   {0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9},
+   {0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652},
+   {0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e},
+   {0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664},
+   {0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911},
+   {0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73},
+   {0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8},
+   {0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2},
+};
+
+class adler32_variant : public ::testing::TestWithParam<adler32_test> {
+public:
+    void hash(adler32_test param, adler32_func adler32) {
+        uint32_t adler = adler32((uint32_t)param.adler, param.buf, param.len);
+        EXPECT_EQ(adler, param.expect);
+    }
 };
 
-static const int test_size = sizeof(tests) / sizeof(tests[0]);
+INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests));
 
-int main(void) {
-    int i;
-    for (i = 0; i < test_size; i++) {
-        test_adler32(tests[i].adler, tests[i].buf, tests[i].len, tests[i].expect, tests[i].line);
+#define TEST_ADLER32(name, func, support_flag) \
+    TEST_P(adler32_variant, name) { \
+        if (!support_flag) { \
+            GTEST_SKIP(); \
+            return; \
+        } \
+        hash(GetParam(), func); \
     }
 
-    return 0;
-}
+TEST_ADLER32(c, adler32_c, 1)
+
+#ifdef ARM_NEON_ADLER32
+TEST_ADLER32(neon, adler32_neon, arm_cpu_has_neon)
+#elif defined(POWER8_VSX_ADLER32)
+TEST_ADLER32(power8, adler32_power8, power_cpu_has_arch_2_07)
+#elif defined(PPC_VMX_ADLER32)
+TEST_ADLER32(vmx, adler32_vmx, power_cpu_has_altivec)
+#endif
+
+#ifdef X86_SSSE3_ADLER32
+TEST_ADLER32(ssse3, adler32_ssse3, x86_cpu_has_ssse3)
+#endif
+#ifdef X86_SSE41_ADLER32
+TEST_ADLER32(sse41, adler32_sse41, x86_cpu_has_sse41)
+#endif
+#ifdef X86_AVX2_ADLER32
+TEST_ADLER32(avx2, adler32_avx2, x86_cpu_has_avx2)
+#endif
+#ifdef X86_AVX512_ADLER32
+TEST_ADLER32(avx512, adler32_avx512, x86_cpu_has_avx512)
+#endif
+#ifdef X86_AVX512VNNI_ADLER32
+TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, x86_cpu_has_avx512vnni)
+#endif
diff --git a/test/test_compress.cc b/test/test_compress.cc
new file mode 100644 (file)
index 0000000..9885b33
--- /dev/null
@@ -0,0 +1,33 @@
+/* test_compress.cc - Test compress() and uncompress() using hello world string */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(compress, basic) {
+    uint8_t compr[128], uncompr[128];
+    z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    int err;
+
+    err = PREFIX(compress)(compr, &compr_len, (const unsigned char *)hello, hello_len);
+    EXPECT_EQ(err, Z_OK);
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = PREFIX(uncompress)(uncompr, &uncompr_len, compr, compr_len);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_STREQ((char *)uncompr, (char *)hello);
+}
diff --git a/test/test_crc32.c b/test/test_crc32.c
deleted file mode 100644 (file)
index 83718eb..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* test_crc32.c -- crc32 unit test
- * Copyright (C) 2019-2021 IBM Corporation
- * Authors: Rogerio Alves    <rogealve@br.ibm.com>
- *          Matheus Castanho <msc@linux.ibm.com>
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-#  include "zlib.h"
-#else
-#  include "zlib-ng.h"
-#endif
-
-#include <stdio.h>
-
-typedef struct {
-    uint32_t line;
-    unsigned long crc;
-    const unsigned char *buf;
-    size_t len;
-    unsigned long expect;
-} crc32_test;
-
-void test_crc32(unsigned long crc, const unsigned char *buf, size_t len, uint32_t chk, uint32_t line) {
-    uint32_t res = PREFIX(crc32_z)((uint32_t)crc, buf, len);
-    if (res != chk) {
-        fprintf(stderr, "FAIL [%d]: crc32 returned 0x%08X expected 0x%08X\n",
-                line, res, chk);
-        exit(1);
-    }
-}
-
-static const crc32_test tests[] = {
-  {__LINE__, 0x0, (const unsigned char *)0x0, 0, 0x0},
-  {__LINE__, 0xffffffff, (const unsigned char *)0x0, 0, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)0x0, 255, 0x0}, /*  BZ 174799.  */
-  {__LINE__, 0x0, (const unsigned char *)0x0, 256, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)0x0, 257, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)0x0, 32767, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)0x0, 32768, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)0x0, 32769, 0x0},
-  {__LINE__, 0x0, (const unsigned char *)"", 0, 0x0},
-  {__LINE__, 0xffffffff, (const unsigned char *)"", 0, 0xffffffff},
-  {__LINE__, 0x0, (const unsigned char *)"abacus", 6, 0xc3d7115b},
-  {__LINE__, 0x0, (const unsigned char *)"backlog", 7, 0x269205},
-  {__LINE__, 0x0, (const unsigned char *)"campfire", 8, 0x22a515f8},
-  {__LINE__, 0x0, (const unsigned char *)"delta", 5, 0x9643fed9},
-  {__LINE__, 0x0, (const unsigned char *)"executable", 10, 0xd68eda01},
-  {__LINE__, 0x0, (const unsigned char *)"file", 4, 0x8c9f3610},
-  {__LINE__, 0x0, (const unsigned char *)"greatest", 8, 0xc1abd6cd},
-  {__LINE__, 0x0, (const unsigned char *)"hello", 5, 0x3610a686},
-  {__LINE__, 0x0, (const unsigned char *)"inverter", 8, 0xc9e962c9},
-  {__LINE__, 0x0, (const unsigned char *)"jigsaw", 6, 0xce4e3f69},
-  {__LINE__, 0x0, (const unsigned char *)"karate", 6, 0x890be0e2},
-  {__LINE__, 0x0, (const unsigned char *)"landscape", 9, 0xc4e0330b},
-  {__LINE__, 0x0, (const unsigned char *)"machine", 7, 0x1505df84},
-  {__LINE__, 0x0, (const unsigned char *)"nanometer", 9, 0xd4e19f39},
-  {__LINE__, 0x0, (const unsigned char *)"oblivion", 8, 0xdae9de77},
-  {__LINE__, 0x0, (const unsigned char *)"panama", 6, 0x66b8979c},
-  {__LINE__, 0x0, (const unsigned char *)"quest", 5, 0x4317f817},
-  {__LINE__, 0x0, (const unsigned char *)"resource", 8, 0xbc91f416},
-  {__LINE__, 0x0, (const unsigned char *)"secret", 6, 0x5ca2e8e5},
-  {__LINE__, 0x0, (const unsigned char *)"test", 4, 0xd87f7e0c},
-  {__LINE__, 0x0, (const unsigned char *)"ultimate", 8, 0x3fc79b0b},
-  {__LINE__, 0x0, (const unsigned char *)"vector", 6, 0x1b6e485b},
-  {__LINE__, 0x0, (const unsigned char *)"walrus", 6, 0xbe769b97},
-  {__LINE__, 0x0, (const unsigned char *)"xeno", 4, 0xe7a06444},
-  {__LINE__, 0x0, (const unsigned char *)"yelling", 7, 0xfe3944e5},
-  {__LINE__, 0x0, (const unsigned char *)"zlib", 4, 0x73887d3a},
-  {__LINE__, 0x0, (const unsigned char *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1},
-  {__LINE__, 0x0, (const unsigned char *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e},
-  {__LINE__, 0x0, (const unsigned char *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76},
-  {__LINE__, 0x0, (const unsigned char *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a},
-  {__LINE__, 0x0, (const unsigned char *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d},
-  {__LINE__, 0x0, (const unsigned char *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5},
-  {__LINE__, 0x0, (const unsigned char *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11},
-  {__LINE__, 0x0, (const unsigned char *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac},
-  {__LINE__, 0x0, (const unsigned char *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb},
-  {__LINE__, 0x0, (const unsigned char *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9},
-  {__LINE__, 0x0, (const unsigned char *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37},
-  {__LINE__, 0x0, (const unsigned char *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0},
-  {__LINE__, 0x0, (const unsigned char *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29},
-  {__LINE__, 0x0, (const unsigned char *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8},
-  {__LINE__, 0x0, (const unsigned char *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192},
-  {__LINE__, 0x0, (const unsigned char *)"70684206568419061514", 20, 0x59a179f0},
-  {__LINE__, 0x0, (const unsigned char *)"42015093765128581010", 20, 0xcd1013d7},
-  {__LINE__, 0x0, (const unsigned char *)"88214814356148806939", 20, 0xab927546},
-  {__LINE__, 0x0, (const unsigned char *)"43472694284527343838", 20, 0x11f3b20c},
-  {__LINE__, 0x0, (const unsigned char *)"49769333513942933689", 20, 0xd562d4ca},
-  {__LINE__, 0x0, (const unsigned char *)"54979784887993251199", 20, 0x233395f7},
-  {__LINE__, 0x0, (const unsigned char *)"58360544869206793220", 20, 0x2d167fd5},
-  {__LINE__, 0x0, (const unsigned char *)"27347953487840714234", 20, 0x8b5108ba},
-  {__LINE__, 0x0, (const unsigned char *)"07650690295365319082", 20, 0xc46b3cd8},
-  {__LINE__, 0x0, (const unsigned char *)"42655507906821911703", 20, 0xc10b2662},
-  {__LINE__, 0x0, (const unsigned char *)"29977409200786225655", 20, 0xc9a0f9d2},
-  {__LINE__, 0x0, (const unsigned char *)"85181542907229116674", 20, 0x9341357b},
-  {__LINE__, 0x0, (const unsigned char *)"87963594337989416799", 20, 0xf0424937},
-  {__LINE__, 0x0, (const unsigned char *)"21395988329504168551", 20, 0xd7c4c31f},
-  {__LINE__, 0x0, (const unsigned char *)"51991013580943379423", 20, 0xf11edcc4},
-  {__LINE__, 0x0, (const unsigned char *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4},
-  {__LINE__, 0x0, (const unsigned char *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631},
-  {__LINE__, 0x0, (const unsigned char *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99},
-  {__LINE__, 0x0, (const unsigned char *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac},
-  {__LINE__, 0x0, (const unsigned char *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9},
-  {__LINE__, 0x0, (const unsigned char *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf},
-  {__LINE__, 0x0, (const unsigned char *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac},
-  {__LINE__, 0x0, (const unsigned char *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388},
-  {__LINE__, 0x0, (const unsigned char *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d},
-  {__LINE__, 0x0, (const unsigned char *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5},
-  {__LINE__, 0x0, (const unsigned char *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9},
-  {__LINE__, 0x0, (const unsigned char *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777},
-  {__LINE__, 0x0, (const unsigned char *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048},
-  {__LINE__, 0x7a30360d, (const unsigned char *)"abacus", 6, 0xf8655a84},
-  {__LINE__, 0x6fd767ee, (const unsigned char *)"backlog", 7, 0x1ed834b1},
-  {__LINE__, 0xefeb7589, (const unsigned char *)"campfire", 8, 0x686cfca},
-  {__LINE__, 0x61cf7e6b, (const unsigned char *)"delta", 5, 0x1554e4b1},
-  {__LINE__, 0xdc712e2,  (const unsigned char *)"executable", 10, 0x761b4254},
-  {__LINE__, 0xad23c7fd, (const unsigned char *)"file", 4, 0x7abdd09b},
-  {__LINE__, 0x85cb2317, (const unsigned char *)"greatest", 8, 0x4ba91c6b},
-  {__LINE__, 0x9eed31b0, (const unsigned char *)"inverter", 8, 0xd5e78ba5},
-  {__LINE__, 0xb94f34ca, (const unsigned char *)"jigsaw", 6, 0x23649109},
-  {__LINE__, 0xab058a2,  (const unsigned char *)"karate", 6, 0xc5591f41},
-  {__LINE__, 0x5bff2b7a, (const unsigned char *)"landscape", 9, 0xf10eb644},
-  {__LINE__, 0x605c9a5f, (const unsigned char *)"machine", 7, 0xbaa0a636},
-  {__LINE__, 0x51bdeea5, (const unsigned char *)"nanometer", 9, 0x6af89afb},
-  {__LINE__, 0x85c21c79, (const unsigned char *)"oblivion", 8, 0xecae222b},
-  {__LINE__, 0x97216f56, (const unsigned char *)"panama", 6, 0x47dffac4},
-  {__LINE__, 0x18444af2, (const unsigned char *)"quest", 5, 0x70c2fe36},
-  {__LINE__, 0xbe6ce359, (const unsigned char *)"resource", 8, 0x1471d925},
-  {__LINE__, 0x843071f1, (const unsigned char *)"secret", 6, 0x50c9a0db},
-  {__LINE__, 0xf2480c60, (const unsigned char *)"ultimate", 8, 0xf973daf8},
-  {__LINE__, 0x2d2feb3d, (const unsigned char *)"vector", 6, 0x344ac03d},
-  {__LINE__, 0x7490310a, (const unsigned char *)"walrus", 6, 0x6d1408ef},
-  {__LINE__, 0x97d247d4, (const unsigned char *)"xeno", 4, 0xe62670b5},
-  {__LINE__, 0x93cf7599, (const unsigned char *)"yelling", 7, 0x1b36da38},
-  {__LINE__, 0x73c84278, (const unsigned char *)"zlib", 4, 0x6432d127},
-  {__LINE__, 0x228a87d1, (const unsigned char *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0},
-  {__LINE__, 0xa7a048d0, (const unsigned char *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274},
-  {__LINE__, 0x1f0ded40, (const unsigned char *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870},
-  {__LINE__, 0xa804a62f, (const unsigned char *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd},
-  {__LINE__, 0x508fae6a, (const unsigned char *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc},
-  {__LINE__, 0xe5adaf4f, (const unsigned char *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178},
-  {__LINE__, 0x67136a40, (const unsigned char *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070},
-  {__LINE__, 0xb00c4a10, (const unsigned char *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0},
-  {__LINE__, 0x2e0c84b5, (const unsigned char *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72},
-  {__LINE__, 0x81238d44, (const unsigned char *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620},
-  {__LINE__, 0xf853aa92, (const unsigned char *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d},
-  {__LINE__, 0x5a692325, (const unsigned char *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24},
-  {__LINE__, 0x3275b9f,  (const unsigned char *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df},
-  {__LINE__, 0x38371feb, (const unsigned char *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30},
-  {__LINE__, 0xafc8bf62, (const unsigned char *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9},
-  {__LINE__, 0x9b07db73, (const unsigned char *)"70684206568419061514", 20, 0xae1fb7b7},
-  {__LINE__, 0xe75b214,  (const unsigned char *)"42015093765128581010", 20, 0xd4eecd2d},
-  {__LINE__, 0x72d0fe6f, (const unsigned char *)"88214814356148806939", 20, 0x4660ec7},
-  {__LINE__, 0xf857a4b1, (const unsigned char *)"43472694284527343838", 20, 0xfd8afdf7},
-  {__LINE__, 0x54b8e14,  (const unsigned char *)"49769333513942933689", 20, 0xc6d1b5f2},
-  {__LINE__, 0xd6aa5616, (const unsigned char *)"54979784887993251199", 20, 0x32476461},
-  {__LINE__, 0x11e63098, (const unsigned char *)"58360544869206793220", 20, 0xd917cf1a},
-  {__LINE__, 0xbe92385,  (const unsigned char *)"27347953487840714234", 20, 0x4ad14a12},
-  {__LINE__, 0x49511de0, (const unsigned char *)"07650690295365319082", 20, 0xe37b5c6c},
-  {__LINE__, 0x3db13bc1, (const unsigned char *)"42655507906821911703", 20, 0x7cc497f1},
-  {__LINE__, 0xbb899bea, (const unsigned char *)"29977409200786225655", 20, 0x99781bb2},
-  {__LINE__, 0xf6cd9436, (const unsigned char *)"85181542907229116674", 20, 0x132256a1},
-  {__LINE__, 0x9109e6c3, (const unsigned char *)"87963594337989416799", 20, 0xbfdb2c83},
-  {__LINE__, 0x75770fc,  (const unsigned char *)"21395988329504168551", 20, 0x8d9d1e81},
-  {__LINE__, 0x69b1d19b, (const unsigned char *)"51991013580943379423", 20, 0x7b6d4404},
-  {__LINE__, 0xc6132975, (const unsigned char *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010},
-  {__LINE__, 0xd58cb00c, (const unsigned char *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3},
-  {__LINE__, 0xb63b8caa, (const unsigned char *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f},
-  {__LINE__, 0x8a45a2b8, (const unsigned char *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de},
-  {__LINE__, 0xcbe95b78, (const unsigned char *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59},
-  {__LINE__, 0x4ef8a54b, (const unsigned char *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f},
-  {__LINE__, 0x76ad267a, (const unsigned char *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac},
-  {__LINE__, 0x569e613c, (const unsigned char *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66},
-  {__LINE__, 0x36aa61da, (const unsigned char *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7},
-  {__LINE__, 0xf67222df, (const unsigned char *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a},
-  {__LINE__, 0x74b34fd3, (const unsigned char *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060},
-  {__LINE__, 0x351fd770, (const unsigned char *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312},
-  {__LINE__, 0xc45aef77, (const unsigned char *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912},
-  {__LINE__, 0xc45aef77, (const unsigned char *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
-                         "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
-                         "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
-                         "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
-                         "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
-                         "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B}
-};
-
-static const int test_size = sizeof(tests) / sizeof(tests[0]);
-
-int main(void) {
-    int i;
-    for (i = 0; i < test_size; i++) {
-        test_crc32(tests[i].crc, tests[i].buf, tests[i].len, tests[i].expect, tests[i].line);
-    }
-    return 0;
-}
diff --git a/test/test_crc32.cc b/test/test_crc32.cc
new file mode 100644 (file)
index 0000000..af0dd3b
--- /dev/null
@@ -0,0 +1,219 @@
+/* test_crc32.cc -- crc32 unit test
+ * Copyright (C) 2019-2021 IBM Corporation
+ * Authors: Rogerio Alves    <rogealve@br.ibm.com>
+ *          Matheus Castanho <msc@linux.ibm.com>
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" {
+#  include "zbuild.h"
+#  include "zutil_p.h"
+#  include "cpu_features.h"
+}
+
+#include <gtest/gtest.h>
+
+typedef struct {
+    unsigned long crc;
+    const uint8_t *buf;
+    size_t len;
+    unsigned long expect;
+} crc32_test;
+
+static const crc32_test tests[] = {
+  {0x0, (const uint8_t *)0x0, 0, 0x0},
+  {0xffffffff, (const uint8_t *)0x0, 0, 0x0},
+  {0x0, (const uint8_t *)0x0, 255, 0x0}, /*  BZ 174799.  */
+  {0x0, (const uint8_t *)0x0, 256, 0x0},
+  {0x0, (const uint8_t *)0x0, 257, 0x0},
+  {0x0, (const uint8_t *)0x0, 32767, 0x0},
+  {0x0, (const uint8_t *)0x0, 32768, 0x0},
+  {0x0, (const uint8_t *)0x0, 32769, 0x0},
+  {0x0, (const uint8_t *)"", 0, 0x0},
+  {0xffffffff, (const uint8_t *)"", 0, 0xffffffff},
+  {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b},
+  {0x0, (const uint8_t *)"backlog", 7, 0x269205},
+  {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8},
+  {0x0, (const uint8_t *)"delta", 5, 0x9643fed9},
+  {0x0, (const uint8_t *)"executable", 10, 0xd68eda01},
+  {0x0, (const uint8_t *)"file", 4, 0x8c9f3610},
+  {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd},
+  {0x0, (const uint8_t *)"hello", 5, 0x3610a686},
+  {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9},
+  {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69},
+  {0x0, (const uint8_t *)"karate", 6, 0x890be0e2},
+  {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b},
+  {0x0, (const uint8_t *)"machine", 7, 0x1505df84},
+  {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39},
+  {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77},
+  {0x0, (const uint8_t *)"panama", 6, 0x66b8979c},
+  {0x0, (const uint8_t *)"quest", 5, 0x4317f817},
+  {0x0, (const uint8_t *)"resource", 8, 0xbc91f416},
+  {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5},
+  {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c},
+  {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b},
+  {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b},
+  {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97},
+  {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444},
+  {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5},
+  {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a},
+  {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1},
+  {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e},
+  {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76},
+  {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a},
+  {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d},
+  {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5},
+  {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11},
+  {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac},
+  {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb},
+  {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9},
+  {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37},
+  {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0},
+  {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29},
+  {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8},
+  {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192},
+  {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0},
+  {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7},
+  {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546},
+  {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c},
+  {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca},
+  {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7},
+  {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5},
+  {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba},
+  {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8},
+  {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662},
+  {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2},
+  {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b},
+  {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937},
+  {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f},
+  {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4},
+  {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4},
+  {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631},
+  {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99},
+  {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac},
+  {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9},
+  {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf},
+  {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac},
+  {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388},
+  {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d},
+  {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5},
+  {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9},
+  {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777},
+  {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048},
+  {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84},
+  {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1},
+  {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca},
+  {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1},
+  {0xdc712e2,  (const uint8_t *)"executable", 10, 0x761b4254},
+  {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b},
+  {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b},
+  {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5},
+  {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109},
+  {0xab058a2,  (const uint8_t *)"karate", 6, 0xc5591f41},
+  {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644},
+  {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636},
+  {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb},
+  {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b},
+  {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4},
+  {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36},
+  {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925},
+  {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db},
+  {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8},
+  {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d},
+  {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef},
+  {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5},
+  {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38},
+  {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127},
+  {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0},
+  {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274},
+  {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870},
+  {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd},
+  {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc},
+  {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178},
+  {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070},
+  {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0},
+  {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72},
+  {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620},
+  {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d},
+  {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24},
+  {0x3275b9f,  (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df},
+  {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30},
+  {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9},
+  {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7},
+  {0xe75b214,  (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d},
+  {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7},
+  {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7},
+  {0x54b8e14,  (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2},
+  {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461},
+  {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a},
+  {0xbe92385,  (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12},
+  {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c},
+  {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1},
+  {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2},
+  {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1},
+  {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83},
+  {0x75770fc,  (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81},
+  {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404},
+  {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010},
+  {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3},
+  {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f},
+  {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de},
+  {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59},
+  {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f},
+  {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac},
+  {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66},
+  {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7},
+  {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a},
+  {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060},
+  {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312},
+  {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912},
+  {0xc45aef77, (const uint8_t *)
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+    "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B}
+};
+
+class crc32_variant : public ::testing::TestWithParam<crc32_test> {
+public:
+    void hash(crc32_test param, crc32_func crc32) {
+        uint32_t crc = 0;
+        if (param.buf != NULL) {
+            if (param.len) {
+                crc = crc32(param.crc, param.buf, param.len);
+            } else {
+                crc = param.crc;
+            }
+        }
+        EXPECT_EQ(crc, param.expect);
+    }
+};
+
+INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests));
+
+#define TEST_CRC32(name, func, support_flag) \
+    TEST_P(crc32_variant, name) { \
+        if (!support_flag) { \
+            GTEST_SKIP(); \
+            return; \
+        } \
+        hash(GetParam(), func); \
+    }
+
+TEST_CRC32(byfour, crc32_byfour, 1)
+
+#ifdef ARM_ACLE_CRC_HASH
+TEST_CRC32(acle, crc32_acle, arm_cpu_has_crc32)
+#elif defined(POWER8_VSX_CRC32)
+TEST_CRC32(power8, crc32_power8, power_cpu_has_arch_2_07)
+#elif defined(S390_CRC32_VX)
+TEST_CRC32(vx, s390_crc32_vx, s390_cpu_has_vx)
+#elif defined(X86_PCLMULQDQ_CRC)
+TEST_CRC32(pclmulqdq, crc32_pclmulqdq, x86_cpu_has_pclmulqdq)
+#endif
diff --git a/test/test_deflate_bound.cc b/test/test_deflate_bound.cc
new file mode 100644 (file)
index 0000000..d6f576a
--- /dev/null
@@ -0,0 +1,53 @@
+/* test_deflate_bound.cc - Test deflateBound() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, bound) {
+    PREFIX3(stream) c_stream;
+    int estimate_len = 0;
+    uint8_t *out_buf = NULL;
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    c_stream.avail_in = hello_len;
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_out = 0;
+    c_stream.next_out = out_buf;
+
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    /* calculate actual output length and update structure */
+    estimate_len = PREFIX(deflateBound)(&c_stream, hello_len);
+    out_buf = (uint8_t *)malloc(estimate_len);
+
+    if (out_buf != NULL) {
+        /* update zlib configuration */
+        c_stream.avail_out = estimate_len;
+        c_stream.next_out = out_buf;
+
+        /* do the compression */
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        EXPECT_EQ(err, Z_STREAM_END);
+    }
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    free(out_buf);
+}
diff --git a/test/test_deflate_copy.cc b/test/test_deflate_copy.cc
new file mode 100644 (file)
index 0000000..4adc9be
--- /dev/null
@@ -0,0 +1,60 @@
+/* test_deflate_copy.cc - Test deflateCopy() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "deflate.h"
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, copy) {
+    PREFIX3(stream) c_stream, c_stream_copy;
+    uint8_t compr[128];
+    z_size_t compr_len = sizeof(compr);
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&c_stream_copy, 0, sizeof(c_stream_copy));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_EQ(c_stream.state->status, c_stream_copy.state->status);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflateEnd)(&c_stream_copy);
+    EXPECT_EQ(err, Z_OK);
+}
diff --git a/test/test_deflate_dict.cc b/test/test_deflate_dict.cc
new file mode 100644 (file)
index 0000000..7a060a8
--- /dev/null
@@ -0,0 +1,54 @@
+/* test_deflate_dict.cc - Test deflateGetDictionary() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, dictionary) {
+    PREFIX3(stream) c_stream;
+    uint8_t compr[128];
+    uint32_t compr_len = sizeof(compr);
+    uint8_t *dict_new = NULL;
+    uint32_t *dict_len;
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = compr_len;
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_in = (uint32_t)hello_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    dict_new = (uint8_t *)calloc(256, 1);
+    ASSERT_TRUE(dict_new != NULL);
+    dict_len = (uint32_t *)calloc(4, 1);
+    ASSERT_TRUE(dict_len != NULL);
+
+    err = PREFIX(deflateGetDictionary)(&c_stream, dict_new, dict_len);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    free(dict_new);
+    free(dict_len);
+}
diff --git a/test/test_deflate_hash_head_0.cc b/test/test_deflate_hash_head_0.cc
new file mode 100644 (file)
index 0000000..4a4e4b6
--- /dev/null
@@ -0,0 +1,83 @@
+/* Generated by fuzzing - test hash_head == 0 handling. */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, hash_head_0) {
+    PREFIX3(stream) strm;
+    int err;
+
+    memset(&strm, 0, sizeof(strm));
+    err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY);
+    EXPECT_EQ(err, Z_OK);
+
+    unsigned char next_in[9698];
+    memset(next_in, 0x30, sizeof(next_in));
+    next_in[8193] = 0x00;
+    next_in[8194] = 0x00;
+    next_in[8195] = 0x00;
+    next_in[8199] = 0x8a;
+    strm.next_in = next_in;
+    unsigned char next_out[21572];
+    strm.next_out = next_out;
+
+    strm.avail_in = 0;
+    strm.avail_out = 1348;
+    err = PREFIX(deflateParams(&strm, 3, Z_FILTERED));
+    EXPECT_EQ(err, Z_OK);
+
+    strm.avail_in = 6728;
+    strm.avail_out = 2696;
+    err = PREFIX(deflate(&strm, Z_SYNC_FLUSH));
+    EXPECT_EQ(err, Z_OK);
+
+    strm.avail_in = 15;
+    strm.avail_out = 1348;
+    err = PREFIX(deflateParams(&strm, 9, Z_FILTERED));
+    EXPECT_EQ(err, Z_OK);
+
+    strm.avail_in = 1453;
+    strm.avail_out = 1348;
+    err = PREFIX(deflate(&strm, Z_FULL_FLUSH));
+    EXPECT_EQ(err, Z_OK);
+
+    strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in);
+    strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out);
+    err = PREFIX(deflate)(&strm, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    uint32_t compressed_size = (uint32_t)(strm.next_out - next_out);
+
+    err = PREFIX(deflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
+
+    memset(&strm, 0, sizeof(strm));
+    err = PREFIX(inflateInit2)(&strm, -15);
+    EXPECT_EQ(err, Z_OK);
+
+    strm.next_in = next_out;
+    strm.avail_in = compressed_size;
+    unsigned char uncompressed[sizeof(next_in)];
+    strm.next_out = uncompressed;
+    strm.avail_out = sizeof(uncompressed);
+
+    err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(inflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0);
+}
diff --git a/test/test_deflate_header.cc b/test/test_deflate_header.cc
new file mode 100644 (file)
index 0000000..92f4612
--- /dev/null
@@ -0,0 +1,68 @@
+/* test_deflate_header.cc - Test deflateSetHeader() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, header) {
+    PREFIX3(stream) c_stream;
+    PREFIX(gz_header) *head;
+    uint8_t compr[128];
+    z_size_t compr_len = sizeof(compr);
+    int err;
+
+    head = (PREFIX(gz_header) *)calloc(1, sizeof(PREFIX(gz_header)));
+    ASSERT_TRUE(head != NULL);
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    /* gzip */
+    err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
+    EXPECT_EQ(err, Z_OK);
+
+    head->text = 1;
+    head->comment = (uint8_t *)"comment";
+    head->name = (uint8_t *)"name";
+    head->hcrc = 1;
+    head->extra = (uint8_t *)"extra";
+    head->extra_len = (uint32_t)strlen((const char *)head->extra);
+
+    err = PREFIX(deflateSetHeader)(&c_stream, head);
+    EXPECT_EQ(err, Z_OK);
+
+    PREFIX(deflateBound)(&c_stream, (unsigned long)compr_len);
+
+    c_stream.next_in  = (unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    free(head);
+}
diff --git a/test/test_deflate_params.cc b/test/test_deflate_params.cc
new file mode 100644 (file)
index 0000000..f5f5066
--- /dev/null
@@ -0,0 +1,143 @@
+/* test_deflate_params.cc - Test deflate() with dynamic change of compression level */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+
+#include "deflate.h"
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define COMPR_BUFFER_SIZE (48 * 1024)
+#define UNCOMPR_BUFFER_SIZE (64 * 1024)
+#define UNCOMPR_RAND_SIZE (8 * 1024)
+
+TEST(deflate, params) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t *compr, *uncompr;
+    uint32_t compr_len, uncompr_len;
+    uint32_t diff;
+    int32_t i;
+    time_t now;
+    int err;
+#ifndef ZLIB_COMPAT
+    int level = -1;
+    int strategy = -1;
+    zng_deflate_param_value params[2];
+
+    params[0].param = Z_DEFLATE_LEVEL;
+    params[0].buf = &level;
+    params[0].size = sizeof(level);
+
+    params[1].param = Z_DEFLATE_STRATEGY;
+    params[1].buf = &strategy;
+    params[1].size = sizeof(strategy);
+#endif
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&d_stream, 0, sizeof(d_stream));
+
+    compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE);
+    ASSERT_TRUE(compr != NULL);
+    uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE);
+    ASSERT_TRUE(uncompr != NULL);
+
+    compr_len = COMPR_BUFFER_SIZE;
+    uncompr_len = UNCOMPR_BUFFER_SIZE;
+
+    srand((unsigned)time(&now));
+    for (i = 0; i < UNCOMPR_RAND_SIZE; i++)
+        uncompr[i] = (uint8_t)(rand() % 256);
+
+    err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = compr_len;
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = uncompr_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+    EXPECT_EQ(c_stream.avail_in, 0);
+
+    /* Feed in already compressed data and switch to no compression: */
+#ifndef ZLIB_COMPAT
+    zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+    EXPECT_EQ(level, Z_BEST_SPEED);
+    EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY);
+
+    level = Z_NO_COMPRESSION;
+    strategy = Z_DEFAULT_STRATEGY;
+    zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+#else
+    PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+#endif
+
+    c_stream.next_in = compr;
+    diff = (unsigned int)(c_stream.next_out - compr);
+    c_stream.avail_in = diff;
+    err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+
+    /* Switch back to compressing mode: */
+#ifndef ZLIB_COMPAT
+    level = -1;
+    strategy = -1;
+    zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+    EXPECT_EQ(level, Z_NO_COMPRESSION);
+    EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY);
+
+    level = Z_BEST_COMPRESSION;
+    strategy = Z_FILTERED;
+    zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+#else
+    PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+#endif
+
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (unsigned int)uncompr_len;
+    err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (unsigned int)compr_len;
+
+    err = PREFIX(inflateInit)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    do {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = uncompr_len;
+        err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END)
+            break;
+        EXPECT_EQ(err, Z_OK);
+    } while (err == Z_OK);
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_EQ(d_stream.total_out, (2 * uncompr_len) + diff);
+
+    free(compr);
+    free(uncompr);
+}
diff --git a/test/test_deflate_pending.cc b/test/test_deflate_pending.cc
new file mode 100644 (file)
index 0000000..b107dd4
--- /dev/null
@@ -0,0 +1,66 @@
+/* test_deflate_pending.cc - Test deflatePending() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, pending) {
+    PREFIX3(stream) c_stream;
+    uint8_t compr[128];
+    z_size_t compr_len = sizeof(compr);
+    int *bits;
+    unsigned *ped;
+    int err;
+
+
+    bits = (int *)calloc(256, 1);
+    ASSERT_TRUE(bits != NULL);
+    ped = (unsigned *)calloc(256, 1);
+    ASSERT_TRUE(ped != NULL);
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflatePending)(&c_stream, ped, bits);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_GE(*bits, 0);
+    EXPECT_LE(*bits, 7);
+
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    free(bits);
+    free(ped);
+}
diff --git a/test/test_deflate_prime.cc b/test/test_deflate_prime.cc
new file mode 100644 (file)
index 0000000..135a2d4
--- /dev/null
@@ -0,0 +1,91 @@
+/* test_deflate_prime.cc - Test deflatePrime() wrapping gzip around deflate stream */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, prime) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t compr[128], uncompr[128];
+    z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    uint32_t crc = 0;
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&d_stream, 0, sizeof(d_stream));
+
+    /* Raw deflate windowBits is -15 */
+    err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
+    EXPECT_EQ(err, Z_OK);
+
+    /* Gzip magic number */
+    err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip compression method (deflate) */
+    err = PREFIX(deflatePrime)(&c_stream, 8, 0x08);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip flags (one byte, using two odd bit calls) */
+    err = PREFIX(deflatePrime)(&c_stream, 3, 0x0);
+    EXPECT_EQ(err, Z_OK);
+    err = PREFIX(deflatePrime)(&c_stream, 5, 0x0);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip modified time */
+    err = PREFIX(deflatePrime)(&c_stream, 32, 0x0);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip extra flags */
+    err = PREFIX(deflatePrime)(&c_stream, 8, 0x0);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip operating system */
+    err = PREFIX(deflatePrime)(&c_stream, 8, 255);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_in = (uint32_t)hello_len;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uint32_t)compr_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    /* Gzip uncompressed data crc32 */
+    crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len);
+    err = PREFIX(deflatePrime)(&c_stream, 32, crc);
+    EXPECT_EQ(err, Z_OK);
+    /* Gzip uncompressed data length */
+    err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)hello_len);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uint32_t)c_stream.total_out;
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uint32_t)uncompr_len;
+    d_stream.total_in = 0;
+    d_stream.total_out = 0;
+
+    /* Inflate with gzip header */
+    err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(inflate)(&d_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_BUF_ERROR);
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_STREQ((char *)uncompr, hello);
+}
similarity index 84%
rename from test/test_deflate_quick_bi_valid.c
rename to test/test_deflate_quick_bi_valid.cc
index 0a60081f4e8016da376f19b7808abccca1378b4c..8ce4c229db178fa8084373945554568dcad70ac0 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-int main() {
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate_quick, bi_valid) {
     PREFIX3(stream) strm;
+    int err;
+
     memset(&strm, 0, sizeof(strm));
 
-    int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED);
+    EXPECT_EQ(err, Z_OK);
 
     z_const unsigned char next_in[554] = {
         0x8d, 0xff, 0xff, 0xff, 0xa2, 0x00, 0x00, 0xff, 0x00, 0x15, 0x1b, 0x1b, 0xa2, 0xa2, 0xaf, 0xa2,
@@ -63,24 +66,15 @@ int main() {
 
     strm.avail_in = 554;
     strm.avail_out = 31;
-    ret = PREFIX(deflate)(&strm, Z_FINISH);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+
+    err = PREFIX(deflate)(&strm, Z_FINISH);
+    EXPECT_EQ(err, Z_OK);
 
     strm.avail_in = 0;
     strm.avail_out = 498;
-    ret = PREFIX(deflate)(&strm, Z_FINISH);
-    if (ret != Z_STREAM_END) {
-        fprintf(stderr, "deflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(deflate)(&strm, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
 
-    ret = PREFIX(deflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-    return 0;
+    err = PREFIX(deflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
 }
similarity index 71%
rename from test/test_deflate_quick_block_open.c
rename to test/test_deflate_quick_block_open.cc
index 9df9212000956cb444ef6049578875cc3f84ea0c..b8703ae97735cb01fcb2c1346774137aeb2ac0f1 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-int main() {
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate_quick, block_open) {
     PREFIX3(stream) strm;
+    int err;
 
     memset(&strm, 0, sizeof(strm));
-    int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 1, Z_FILTERED);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 1, Z_FILTERED);
+    EXPECT_EQ(err, Z_OK);
 
-    z_const unsigned char next_in[494] =
+    z_const unsigned char next_in[495] =
             "\x1d\x1d\x00\x00\x00\x4a\x4a\x4a\xaf\xaf\xaf\xaf\x4a\x4a\x4a\x4a"
             "\x3f\x3e\xaf\xff\xff\xff\x11\xff\xff\xff\xff\xdf\x00\x00\x00\x01"
             "\x3f\x7d\x00\x50\x00\x00\xc8\x01\x2b\x60\xc8\x00\x24\x06\xff\xff"
@@ -62,28 +64,19 @@ int main() {
         strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out);
         if (strm.avail_out > 38)
             strm.avail_out = 38;
-        ret = PREFIX(deflate)(&strm, Z_FINISH);
-        if (ret == Z_STREAM_END)
+        err = PREFIX(deflate)(&strm, Z_FINISH);
+        if (err == Z_STREAM_END)
             break;
-        if (ret != Z_OK) {
-            fprintf(stderr, "deflate() failed with code %d\n", ret);
-            return EXIT_FAILURE;
-        }
+        EXPECT_EQ(err, Z_OK);
     }
     uint32_t compressed_size = (uint32_t)(strm.next_out - next_out);
 
-    ret = PREFIX(deflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(deflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
 
     memset(&strm, 0, sizeof(strm));
-    ret = PREFIX(inflateInit2)(&strm, -15);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(inflateInit2)(&strm, -15);
+    EXPECT_EQ(err, Z_OK);
 
     strm.next_in = next_out;
     strm.avail_in = compressed_size;
@@ -91,21 +84,11 @@ int main() {
     strm.next_out = uncompressed;
     strm.avail_out = sizeof(uncompressed);
 
-    ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
-    if (ret != Z_STREAM_END) {
-        fprintf(stderr, "inflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_STREAM_END);
 
-    ret = PREFIX(inflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(inflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
 
-    if (memcmp(uncompressed, next_in, sizeof(uncompressed)) != 0) {
-        fprintf(stderr, "Uncompressed data differs from the original\n");
-        return EXIT_FAILURE;
-    }
-    return 0;
+    EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0);
 }
diff --git a/test/test_deflate_tune.cc b/test/test_deflate_tune.cc
new file mode 100644 (file)
index 0000000..9921ee6
--- /dev/null
@@ -0,0 +1,56 @@
+/* test_deflate_tune.cc - Test deflateTune() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, tune) {
+    PREFIX3(stream) c_stream;
+    uint8_t compr[128];
+    z_size_t compr_len = sizeof(compr);
+    int err;
+    int good_length = 3;
+    int max_lazy = 5;
+    int nice_length = 18;
+    int max_chain = 6;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflateTune)(&c_stream, good_length, max_lazy,nice_length, max_chain);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+}
diff --git a/test/test_dict.cc b/test/test_dict.cc
new file mode 100644 (file)
index 0000000..223f0a6
--- /dev/null
@@ -0,0 +1,95 @@
+/* test_dict.cc - Test deflate() and inflate() with preset dictionary */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+/* Maximum dictionary size, according to inflateGetDictionary() description. */
+#define MAX_DICTIONARY_SIZE 32768
+
+static const char dictionary[] = "hello";
+
+TEST(dictionary, basic) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t compr[128], uncompr[128];
+    z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    uint32_t dict_adler = 0;
+    uint8_t check_dict[MAX_DICTIONARY_SIZE];
+    uint32_t check_dict_len = 0;
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&d_stream, 0, sizeof(d_stream));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(deflateSetDictionary)(&c_stream,
+        (const unsigned char *)dictionary, (int)sizeof(dictionary));
+    EXPECT_EQ(err, Z_OK);
+
+    dict_adler = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uint32_t)compr_len;
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_in = (uint32_t)hello_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    strcpy((char*)uncompr, "garbage garbage garbage");
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (unsigned int)compr_len;
+
+    err = PREFIX(inflateInit)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (unsigned int)uncompr_len;
+
+    for (;;) {
+        err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END)
+            break;
+        if (err == Z_NEED_DICT) {
+            EXPECT_EQ(d_stream.adler, dict_adler);
+            err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary,
+                (uint32_t)sizeof(dictionary));
+        }
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dict_len);
+    EXPECT_EQ(err, Z_OK);
+#ifndef S390_DFLTCC_INFLATE
+    EXPECT_GE(check_dict_len, sizeof(dictionary));
+#endif
+
+    err = PREFIX(inflateGetDictionary)(&d_stream, check_dict, &check_dict_len);
+    EXPECT_EQ(err, Z_OK);
+#ifndef S390_DFLTCC_INFLATE
+    EXPECT_TRUE(memcmp(dictionary, check_dict, sizeof(dictionary)) == 0);
+#endif
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_TRUE(strncmp((char*)uncompr, hello, sizeof(hello)) == 0);
+}
diff --git a/test/test_gzio.cc b/test/test_gzio.cc
new file mode 100644 (file)
index 0000000..46baa02
--- /dev/null
@@ -0,0 +1,105 @@
+/* test_gzio.cc - Test read/write of .gz files */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define TESTFILE "foo.gz"
+
+TEST(gzip, readwrite) {
+#ifdef NO_GZCOMPRESS
+    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+    GTEST_SKIP();
+#else
+    uint8_t compr[128], uncompr[128];
+    uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    size_t read;
+    int64_t pos;
+    gzFile file;
+    int err;
+
+    /* Write gz file with test data */
+    file = PREFIX(gzopen)(TESTFILE, "wb");
+    ASSERT_TRUE(file != NULL);
+    /* Write hello, hello! using gzputs and gzprintf */
+    PREFIX(gzputc)(file, 'h');
+    EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4);
+    EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8);
+    /* Write string null-teriminator using gzseek */
+    EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0);
+    /* Write hello, hello! using gzfwrite using best compression level */
+    EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK);
+    EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0);
+    /* Flush compressed bytes to file */
+    EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK);
+    compr_len = (uint32_t)PREFIX(gzoffset)(file);
+    EXPECT_GE(compr_len, 0UL);
+    PREFIX(gzclose)(file);
+
+    /* Open gz file we previously wrote */
+    file = PREFIX(gzopen)(TESTFILE, "rb");
+    ASSERT_TRUE(file != NULL);
+
+    /* Read uncompressed data - hello, hello! string twice */
+    strcpy((char*)uncompr, "garbages");
+    EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len));
+    EXPECT_STREQ((char*)uncompr, hello);
+
+    /* Check position at the end of the gz file */
+    EXPECT_EQ(PREFIX(gzeof)(file), 1);
+
+    /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
+    pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
+    EXPECT_EQ(pos, 6);
+    EXPECT_EQ(PREFIX(gztell)(file), pos);
+    EXPECT_EQ(PREFIX(gzgetc)(file), ' ');
+    EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' ');
+    /* Read first hello, hello! string with gzgets */
+    strcpy((char*)uncompr, "garbages");
+    PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len);
+    EXPECT_EQ(strlen((char*)uncompr), 7); /* " hello!" */
+    EXPECT_STREQ((char*)uncompr, hello + 6);
+
+    /* Seek to second hello, hello! string */
+    pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
+    EXPECT_EQ(pos, 14);
+    EXPECT_EQ(PREFIX(gztell)(file), pos);
+
+    /* Check position not at end of file */
+    EXPECT_EQ(PREFIX(gzeof)(file), 0);
+    /* Read first hello, hello! string with gzfread */
+    strcpy((char*)uncompr, "garbages");
+    read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file);
+    EXPECT_STREQ((const char *)uncompr, hello);
+
+    pos = PREFIX(gzoffset)(file);
+    EXPECT_GE(pos, 0);
+    EXPECT_EQ(pos, (compr_len + 10));
+
+    /* Trigger an error and clear it with gzclearerr */
+    PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
+    PREFIX(gzerror)(file, &err);
+    EXPECT_NE(err, 0);
+
+    PREFIX(gzclearerr)(file);
+    PREFIX(gzerror)(file, &err);
+    EXPECT_EQ(err, 0);
+
+    PREFIX(gzclose)(file);
+
+    EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR);
+    Z_UNUSED(read);
+#endif
+}
diff --git a/test/test_hash_head_0.c b/test/test_hash_head_0.c
deleted file mode 100644 (file)
index 1f615c5..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Generated by fuzzing - test hash_head == 0 handling. */
-
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-#  include "zlib.h"
-#else
-#  include "zlib-ng.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main() {
-    PREFIX3(stream) strm;
-    memset(&strm, 0, sizeof(strm));
-
-    int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    unsigned char next_in[9698];
-    memset(next_in, 0x30, sizeof(next_in));
-    next_in[8193] = 0x00;
-    next_in[8194] = 0x00;
-    next_in[8195] = 0x00;
-    next_in[8199] = 0x8a;
-    strm.next_in = next_in;
-    unsigned char next_out[21572];
-    strm.next_out = next_out;
-
-    strm.avail_in = 0;
-    strm.avail_out = 1348;
-    ret = PREFIX(deflateParams(&strm, 3, Z_FILTERED));
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateParams() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    strm.avail_in = 6728;
-    strm.avail_out = 2696;
-    ret = PREFIX(deflate(&strm, Z_SYNC_FLUSH));
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    strm.avail_in = 15;
-    strm.avail_out = 1348;
-    ret = PREFIX(deflateParams(&strm, 9, Z_FILTERED));
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateParams() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    strm.avail_in = 1453;
-    strm.avail_out = 1348;
-    ret = PREFIX(deflate(&strm, Z_FULL_FLUSH));
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in);
-    strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out);
-    ret = PREFIX(deflate)(&strm, Z_FINISH);
-    if (ret != Z_STREAM_END) {
-        fprintf(stderr, "deflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-    uint32_t compressed_size = (uint32_t)(strm.next_out - next_out);
-
-    ret = PREFIX(deflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    memset(&strm, 0, sizeof(strm));
-    ret = PREFIX(inflateInit2)(&strm, -15);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    strm.next_in = next_out;
-    strm.avail_in = compressed_size;
-    unsigned char uncompressed[sizeof(next_in)];
-    strm.next_out = uncompressed;
-    strm.avail_out = sizeof(uncompressed);
-
-    ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
-    if (ret != Z_STREAM_END) {
-        fprintf(stderr, "inflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    ret = PREFIX(inflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    if (memcmp(uncompressed, next_in, sizeof(uncompressed)) != 0) {
-        fprintf(stderr, "Uncompressed data differs from the original\n");
-        return EXIT_FAILURE;
-    }
-}
similarity index 52%
rename from test/test_inflate_adler32.c
rename to test/test_inflate_adler32.cc
index 3def08e42dd60a9bf07429f2696d8c00d57ac0f3..e17cf6b795de41bdfac7b83d3f9eb955d61384e8 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
 const char* original = "The quick brown fox jumped over the lazy dog";
 
 z_const unsigned char compressed[] = {
-    0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48, 
-    0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d, 
-    0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8, 
+    0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48,
+    0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d,
+    0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8,
     0x49, 0xac, 0xaa, 0x54, 0x48, 0xc9, 0x4f, 0x07, 0x00, 0x6b, 0x93, 0x10, 0x30
 };
 
-int main()
-{
+TEST(inflate, adler32) {
     unsigned char uncompressed[1024];
     PREFIX3(stream) strm;
 
     memset(&strm, 0, sizeof(strm));
 
-    int ret = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateInit2() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    int err = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS);
+    EXPECT_EQ(err, Z_OK);
 
     strm.next_in = compressed;
     strm.avail_in = sizeof(compressed);
     strm.next_out = uncompressed;
     strm.avail_out = sizeof(uncompressed);
 
-    ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
-    if (ret != Z_STREAM_END) {
-        fprintf(stderr, "inflate() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
-
-    ret = PREFIX(inflateEnd)(&strm);
-    if (ret != Z_OK) {
-        fprintf(stderr, "inflateEnd() failed with code %d\n", ret);
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_STREAM_END);
 
-    if (memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) != 0) {
-        fprintf(stderr, "expected output does not match\n");
-        return EXIT_FAILURE;
-    }
+    err = PREFIX(inflateEnd)(&strm);
+    EXPECT_EQ(err, Z_OK);
 
-    return 0;
+    EXPECT_TRUE(memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) == 0);
 }
diff --git a/test/test_inflate_sync.cc b/test/test_inflate_sync.cc
new file mode 100644 (file)
index 0000000..a79d867
--- /dev/null
@@ -0,0 +1,75 @@
+/* test_inflate_sync.cc - Test inflateSync using full flush deflate and corrupted data */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(inflate, sync) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t compr[128], uncompr[128];
+    z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+
+    /* build compressed stream with full flush */
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uint32_t)compr_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+
+    /* force an error in first compressed block */
+    compr[3]++;
+    c_stream.avail_in = hello_len-3;
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    compr_len = (z_size_t)c_stream.total_out;
+
+    memset(&d_stream, 0, sizeof(d_stream));
+    /* just read the zlib header */
+    d_stream.next_in = compr;
+    d_stream.avail_in = 2;
+
+    err = PREFIX(inflateInit)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uint32_t)uncompr_len;
+
+    err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+
+    /* read all compressed data, but skip damaged part */
+    d_stream.avail_in = (uint32_t)compr_len-2;
+    err = PREFIX(inflateSync)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    err = PREFIX(inflate)(&d_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+}
diff --git a/test/test_large_buffers.cc b/test/test_large_buffers.cc
new file mode 100644 (file)
index 0000000..9bf1339
--- /dev/null
@@ -0,0 +1,87 @@
+/* test_large_buffers.cc - Test deflate() and inflate() with large buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define COMPR_BUFFER_SIZE (48 * 1024)
+#define UNCOMPR_BUFFER_SIZE (32 * 1024)
+#define UNCOMPR_RAND_SIZE (8 * 1024)
+
+TEST(deflate, large_buffers) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t *compr, *uncompr;
+    uint32_t compr_len, uncompr_len;
+    int32_t i;
+    time_t now;
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&d_stream, 0, sizeof(d_stream));
+
+    compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE);
+    ASSERT_TRUE(compr != NULL);
+    uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE);
+    ASSERT_TRUE(uncompr != NULL);
+
+    compr_len = COMPR_BUFFER_SIZE;
+    uncompr_len = UNCOMPR_BUFFER_SIZE;
+
+    srand((unsigned)time(&now));
+    for (i = 0; i < UNCOMPR_RAND_SIZE; i++)
+        uncompr[i] = (uint8_t)(rand() % 256);
+
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = compr_len;
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = uncompr_len;
+
+    err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+    EXPECT_EQ(err, Z_OK);
+    EXPECT_EQ(c_stream.avail_in, 0);
+
+    err = PREFIX(deflate)(&c_stream, Z_FINISH);
+    EXPECT_EQ(err, Z_STREAM_END);
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = compr_len;
+    d_stream.next_out = uncompr;
+
+    err = PREFIX(inflateInit)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = uncompr_len;
+        err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_EQ(d_stream.total_out, uncompr_len);
+
+    free(compr);
+    free(uncompr);
+}
diff --git a/test/test_main.cc b/test/test_main.cc
new file mode 100644 (file)
index 0000000..c129db2
--- /dev/null
@@ -0,0 +1,17 @@
+/* test_test.cc - Main entry point for test framework */
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+
+extern "C" {
+#  include "zbuild.h"
+#  include "cpu_features.h"
+}
+
+GTEST_API_ int main(int argc, char **argv) {
+  printf("Running main() from %s\n", __FILE__);
+  cpu_check_features();
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/test/test_shared.h b/test/test_shared.h
new file mode 100644 (file)
index 0000000..f942967
--- /dev/null
@@ -0,0 +1,2 @@
+static const char hello[] = "hello, hello!";
+static const int hello_len = sizeof(hello);
diff --git a/test/test_small_buffers.cc b/test/test_small_buffers.cc
new file mode 100644 (file)
index 0000000..bb3449f
--- /dev/null
@@ -0,0 +1,69 @@
+/* test_small_buffers.cc - Test deflate() and inflate() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, small_buffers) {
+    PREFIX3(stream) c_stream, d_stream;
+    uint8_t compr[128], uncompr[128];
+    z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+    int err;
+
+    memset(&c_stream, 0, sizeof(c_stream));
+    memset(&d_stream, 0, sizeof(d_stream));
+
+    err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+    EXPECT_EQ(err, Z_OK);
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+        EXPECT_EQ(err, Z_OK);
+    }
+    /* Finish the stream, still forcing small buffers */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = PREFIX(deflate)(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(deflateEnd)(&c_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.next_in  = compr;
+    d_stream.next_out = uncompr;
+
+    err = PREFIX(inflateInit)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    while (d_stream.total_out < uncompr_len && d_stream.total_in < compr_len) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        EXPECT_EQ(err, Z_OK);
+    }
+
+    err = PREFIX(inflateEnd)(&d_stream);
+    EXPECT_EQ(err, Z_OK);
+
+    EXPECT_STREQ((char*)uncompr, hello);
+}
diff --git a/test/test_version.cc b/test/test_version.cc
new file mode 100644 (file)
index 0000000..fda8790
--- /dev/null
@@ -0,0 +1,27 @@
+/* test_version.cc - Test zVersion() and zlibCompileFlags() */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+#  include "zlib.h"
+#else
+#  include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(version, basic) {
+    static const char *my_version = PREFIX2(VERSION);
+
+    EXPECT_EQ(zVersion()[0], my_version[0]);
+    EXPECT_STREQ(zVersion(), PREFIX2(VERSION));
+
+    printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n",
+            ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)());
+}