Introduce ZLIBNG_ENABLE_TESTS

This patch adds the ability to run zlib-ng test suite against the
original zlib as follows:

    cmake -DZLIB_COMPAT=ON -DZLIBNG_ENABLE_TESTS=OFF .
    make
    LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu make test

The benefit of this is that modifications to the original zlib can be
tested with a more extensive zlib-ng's testsuite, and the assumptions
that the zlib-ng tests make can be validated against the original zlib.

In addition to a number of tests that exercise purely zlib-ng specific
API, there are a few that expect zlib-ng specific behavior from the
original zlib API:

- deflate() (obviously) emits different streams
- zlib-ng's deflatePrime() can take more than 16 bits
- zVersion() returns a different string

Adjust or disable the respective tests for ZLIBNG_ENABLE_TESTS=OFF.
This commit is contained in:
Ilya Leoshkevich 2022-09-28 00:50:36 +02:00 committed by Hans Kristian Rosbach
parent f127bc96fc
commit e63f36b1cf
7 changed files with 80 additions and 21 deletions

View File

@ -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")

View File

@ -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

View File

@ -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} $<TARGET_FILE:infcover>)
# 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} $<TARGET_FILE:infcover>)
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)

View File

@ -15,12 +15,9 @@
#include <stdarg.h>
#include <inttypes.h>
#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);

View File

@ -12,7 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include "test_shared.h"
#include "test_shared_ng.h"
#include <gtest/gtest.h>
@ -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);

View File

@ -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

23
test/test_shared_ng.h Normal file
View File

@ -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