diff options
Diffstat (limited to 'neozip/test/test_deflate.cc')
| -rw-r--r-- | neozip/test/test_deflate.cc | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/neozip/test/test_deflate.cc b/neozip/test/test_deflate.cc new file mode 100644 index 0000000000..4927c821e9 --- /dev/null +++ b/neozip/test/test_deflate.cc @@ -0,0 +1,150 @@ +/* test_deflate.cc -- Test deflate/inflate round-trip with various levels, sizes, and strategies */ + +#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 <gtest/gtest.h> + +#include "compressible_data_p.h" +#include "test_shared.h" + +#define MAX_SIZE (1024 * 1024) + +class deflate_variant : public testing::TestWithParam<std::tuple<size_t, int, int, int>> { +public: + static void SetUpTestSuite() { + inbuf = gen_compressible_data(MAX_SIZE); + ASSERT_TRUE(inbuf != NULL); + } + static void TearDownTestSuite() { + free(inbuf); + inbuf = NULL; + } + void SetUp() override { + compbuf = NULL; + decompbuf = NULL; + } + void TearDown() override { + free(compbuf); + free(decompbuf); + } + + static uint8_t *inbuf; + uint8_t *compbuf; + uint8_t *decompbuf; +}; + +uint8_t *deflate_variant::inbuf = NULL; + +TEST_P(deflate_variant, round_trip) { + size_t size = std::get<0>(GetParam()); + int level = std::get<1>(GetParam()); + int window_bits = std::get<2>(GetParam()); + int strategy = std::get<3>(GetParam()); + PREFIX3(stream) c_stream, d_stream; + int err; + + /* Allocate output buffer */ + unsigned long compbuf_size = PREFIX(deflateBound)(NULL, (unsigned long)size); + compbuf = (uint8_t *)malloc((size_t)compbuf_size); + ASSERT_TRUE(compbuf != NULL); + + /* Compress */ + memset(&c_stream, 0, sizeof(c_stream)); + err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, + window_bits, MAX_MEM_LEVEL, strategy); + ASSERT_EQ(err, Z_OK) << "deflateInit2 failed"; + + c_stream.next_in = inbuf; + c_stream.avail_in = (uint32_t)size; + c_stream.next_out = compbuf; + c_stream.avail_out = (uint32_t)compbuf_size; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + ASSERT_EQ(err, Z_STREAM_END) << + "size: " << size << "\n" << + "level: " << level << "\n" << + "window_bits: " << window_bits << "\n" << + "strategy: " << strategy; + + size_t comp_size = (size_t)c_stream.total_out; + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + /* Decompress and verify round-trip */ + decompbuf = (uint8_t *)malloc(size); + ASSERT_TRUE(decompbuf != NULL); + + memset(&d_stream, 0, sizeof(d_stream)); + err = PREFIX(inflateInit2)(&d_stream, window_bits); + ASSERT_EQ(err, Z_OK) << "inflateInit2 failed"; + + d_stream.next_in = compbuf; + d_stream.avail_in = (uint32_t)comp_size; + d_stream.next_out = decompbuf; + d_stream.avail_out = (uint32_t)size; + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + ASSERT_EQ(err, Z_STREAM_END) << + "size: " << size << "\n" << + "level: " << level << "\n" << + "window_bits: " << window_bits << "\n" << + "strategy: " << strategy; + + EXPECT_EQ(d_stream.total_in, comp_size); + EXPECT_EQ(d_stream.total_out, size); + EXPECT_EQ(memcmp(inbuf, decompbuf, size), 0) << "round-trip data mismatch"; + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); +} + +static std::string deflate_test_name(const testing::TestParamInfo<deflate_variant::ParamType> &info) { + size_t size = std::get<0>(info.param); + int level = std::get<1>(info.param); + int window_bits = std::get<2>(info.param); + int strategy = std::get<3>(info.param); + + char size_str[32]; + if (size >= 1048576 && size % 1048576 == 0) + snprintf(size_str, sizeof(size_str), "%zuM", size / 1048576); + else if (size >= 1024 && size % 1024 == 0) + snprintf(size_str, sizeof(size_str), "%zuK", size / 1024); + else + snprintf(size_str, sizeof(size_str), "%zu", size); + + const char *wrap_str = (window_bits < 0) ? "raw" : "zlib"; + + const char *strategy_str; + switch (strategy) { + case Z_FILTERED: strategy_str = "filtered"; break; + case Z_HUFFMAN_ONLY: strategy_str = "huffman"; break; + case Z_RLE: strategy_str = "rle"; break; + case Z_FIXED: strategy_str = "fixed"; break; + default: strategy_str = "default"; break; + } + + char name[64]; + snprintf(name, sizeof(name), "%s_level%d_%s_%s", size_str, level, wrap_str, strategy_str); + return name; +} + +INSTANTIATE_TEST_SUITE_P(deflate, deflate_variant, + testing::Combine( + testing::Values(1024, 16384, 131072, 1048576), /* size */ + testing::Values(1, 3, 6, 9), /* level */ + testing::Values(MAX_WBITS, -MAX_WBITS), /* window_bits */ + testing::Values(Z_DEFAULT_STRATEGY, Z_FILTERED, + Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED) /* strategy */ + ), + deflate_test_name); |
