diff --git a/CMakeLists.txt b/CMakeLists.txt index 20ca1beb..ca395b2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,7 @@ endif() option(WITH_GZFILEOP "Compile with support for gzFile related functions" ON) option(ZLIB_COMPAT "Compile with zlib compatible API" OFF) option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +option(ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API" ON) option(WITH_FUZZERS "Build test/fuzz" OFF) option(WITH_BENCHMARKS "Build test/benchmarks" OFF) option(WITH_BENCHMARK_APPS "Build application benchmarks" OFF) @@ -1178,6 +1179,7 @@ endif() add_feature_info(WITH_GZFILEOP WITH_GZFILEOP "Compile with support for gzFile related functions") add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Compile with zlib compatible API") add_feature_info(ZLIB_ENABLE_TESTS ZLIB_ENABLE_TESTS "Build test binaries") +add_feature_info(ZLIBNG_ENABLE_TESTS ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API") add_feature_info(WITH_SANITIZER WITH_SANITIZER "Enable sanitizer support") add_feature_info(WITH_FUZZERS WITH_FUZZERS "Build test/fuzz") add_feature_info(WITH_BENCHMARKS WITH_BENCHMARKS "Build test/benchmarks") diff --git a/README.md b/README.md index c2254a43..a1218d44 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,7 @@ Advanced Build Options | WITH_INFLATE_STRICT | | Build with strict inflate distance checking | OFF | | WITH_INFLATE_ALLOW_INVALID_DIST | | Build with zero fill for inflate invalid distances | OFF | | INSTALL_UTILS | | Copy minigzip and minideflate during install | OFF | +| ZLIBNG_ENABLE_TESTS | | Test zlib-ng specific API | ON | Related Projects diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ad002d9c..61322e07 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,6 +9,10 @@ macro(configure_test_executable target) endif() endmacro() +if(ZLIBNG_ENABLE_TESTS) + add_definitions(-DZLIBNG_ENABLE_TESTS) +endif() + add_executable(example example.c) configure_test_executable(example) target_link_libraries(example zlib) @@ -51,7 +55,10 @@ target_link_libraries(infcover zlib) if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) target_sources(infcover PRIVATE ${PROJECT_SOURCE_DIR}/inftrees.c) endif() -add_test(NAME infcover COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +# infcover references zng_inflate_table() and struct inflate_state, which are internal to zlib-ng. +if(ZLIBNG_ENABLE_TESTS) + add_test(NAME infcover COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() add_executable(makefixed ${PROJECT_SOURCE_DIR}/tools/makefixed.c ${PROJECT_SOURCE_DIR}/inftrees.c) configure_test_executable(makefixed) @@ -135,15 +142,12 @@ else() add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) endif() add_library(GTest::GTest ALIAS gtest) + add_library(GTest::Main ALIAS gtest_main) endif() set(TEST_SRCS - test_adler32.cc - test_aligned_alloc.cc - test_compare256.cc test_compress.cc test_compress_bound.cc - test_crc32.cc test_cve-2003-0107.cc test_deflate_bound.cc test_deflate_copy.cc @@ -158,17 +162,27 @@ else() test_deflate_tune.cc test_dict.cc test_inflate_adler32.cc - test_inflate_sync.cc test_large_buffers.cc test_small_buffers.cc - test_version.cc ) if(WITH_GZFILEOP) list(APPEND TEST_SRCS test_gzio.cc) endif() - add_executable(gtest_zlib test_main.cc ${TEST_SRCS}) + if(ZLIBNG_ENABLE_TESTS) + list(APPEND TEST_SRCS + test_adler32.cc # adler32_neon(), etc + test_aligned_alloc.cc # zng_alloc_aligned() + test_compare256.cc # compare256_neon(), etc + test_crc32.cc # crc32_acle(), etc + test_inflate_sync.cc # expects a certain compressed block layout + test_main.cc # cpu_check_features() + test_version.cc # expects a fixed version string + ) + endif() + + add_executable(gtest_zlib ${TEST_SRCS}) configure_test_executable(gtest_zlib) if(WITH_SANITIZER STREQUAL "Memory") @@ -200,7 +214,14 @@ else() target_link_libraries(gtest_zlib external_zlib) endif() - target_link_libraries(gtest_zlib zlibstatic GTest::GTest) + if((NOT ZLIBNG_ENABLE_TESTS) AND ZLIB_COMPAT AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)) + # Link dynamically in order to be able to substitute zlib-ng with zlib. + target_link_libraries(gtest_zlib zlib GTest::Main) + else() + # Link statically in order to test internal zlib-ng functions. + target_link_libraries(gtest_zlib zlibstatic) + endif() + target_link_libraries(gtest_zlib GTest::GTest) find_package(Threads) if(Threads_FOUND) diff --git a/test/example.c b/test/example.c index 33232ded..c6556ed1 100644 --- a/test/example.c +++ b/test/example.c @@ -15,12 +15,9 @@ #include #include -#define TESTFILE "foo.gz" +#include "test_shared_ng.h" -static const char hello[] = "hello, hello!"; -/* "hello world" would be more standard, but the repeated "hello" - * stresses the compression code better, sorry... - */ +#define TESTFILE "foo.gz" static const char dictionary[] = "hello"; static unsigned long dictId = 0; /* Adler32 value of the dictionary */ @@ -437,8 +434,10 @@ void test_flush(unsigned char *compr, z_size_t *comprLen) { *comprLen = (z_size_t)c_stream.total_out; } +#ifdef ZLIBNG_ENABLE_TESTS /* =========================================================================== * Test inflateSync() + * We expect a certain compressed block layout, so skip this with the original zlib. */ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { int err; @@ -474,6 +473,7 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si printf("after inflateSync(): hel%s\n", (char *)uncompr); } +#endif /* =========================================================================== * Test deflate() with preset dictionary @@ -785,7 +785,7 @@ void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *un err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); CHECK_ERR(err, "deflatePrime"); /* Gzip modified time */ - err = PREFIX(deflatePrime)(&c_stream, 32, 0x0); + err = deflate_prime_32(&c_stream, 0); CHECK_ERR(err, "deflatePrime"); /* Gzip extra flags */ err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); @@ -805,10 +805,10 @@ void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *un /* Gzip uncompressed data crc32 */ crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len); - err = PREFIX(deflatePrime)(&c_stream, 32, crc); + err = deflate_prime_32(&c_stream, crc); CHECK_ERR(err, "deflatePrime"); /* Gzip uncompressed data length */ - err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)len); + err = deflate_prime_32(&c_stream, (uint32_t)len); CHECK_ERR(err, "deflatePrime"); err = PREFIX(deflateEnd)(&c_stream); @@ -993,7 +993,9 @@ int main(int argc, char *argv[]) { #endif test_flush(compr, &comprLen); +#ifdef ZLIBNG_ENABLE_TESTS test_sync(compr, comprLen, uncompr, uncomprLen); +#endif comprLen = uncomprLen; test_dict_deflate(compr, comprLen); diff --git a/test/test_deflate_prime.cc b/test/test_deflate_prime.cc index 135a2d43..75dcf317 100644 --- a/test/test_deflate_prime.cc +++ b/test/test_deflate_prime.cc @@ -12,7 +12,7 @@ #include #include -#include "test_shared.h" +#include "test_shared_ng.h" #include @@ -42,7 +42,7 @@ TEST(deflate, prime) { err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); EXPECT_EQ(err, Z_OK); /* Gzip modified time */ - err = PREFIX(deflatePrime)(&c_stream, 32, 0x0); + err = deflate_prime_32(&c_stream, 0x0); EXPECT_EQ(err, Z_OK); /* Gzip extra flags */ err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); @@ -61,10 +61,10 @@ TEST(deflate, prime) { /* Gzip uncompressed data crc32 */ crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len); - err = PREFIX(deflatePrime)(&c_stream, 32, crc); + err = deflate_prime_32(&c_stream, crc); EXPECT_EQ(err, Z_OK); /* Gzip uncompressed data length */ - err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)hello_len); + err = deflate_prime_32(&c_stream, (uint32_t)hello_len); EXPECT_EQ(err, Z_OK); err = PREFIX(deflateEnd)(&c_stream); diff --git a/test/test_shared.h b/test/test_shared.h index f942967e..df92a56b 100644 --- a/test/test_shared.h +++ b/test/test_shared.h @@ -1,2 +1,12 @@ +#ifndef TEST_SHARED_H +#define TEST_SHARED_H + +/* Test definitions that can be used in the original zlib build environment. */ + +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ static const char hello[] = "hello, hello!"; static const int hello_len = sizeof(hello); + +#endif diff --git a/test/test_shared_ng.h b/test/test_shared_ng.h new file mode 100644 index 00000000..81e45199 --- /dev/null +++ b/test/test_shared_ng.h @@ -0,0 +1,23 @@ +#ifndef TEST_SHARED_NG_H +#define TEST_SHARED_NG_H + +#include "test_shared.h" + +/* Test definitions that can only be used in the zlib-ng build environment. */ + +static inline int deflate_prime_32(PREFIX3(stream) *stream, uint32_t value) { + int err; + +#ifdef ZLIBNG_ENABLE_TESTS + err = PREFIX(deflatePrime)(stream, 32, value); +#else + /* zlib's deflatePrime() takes at most 16 bits */ + err = PREFIX(deflatePrime)(stream, 16, value & 0xffff); + if (err != Z_OK) return err; + err = PREFIX(deflatePrime)(stream, 16, value >> 16); +#endif + + return err; +} + +#endif