blob: 4927c821e9947108eb2fc45fed1b9acf700f75cb [file]
/* 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);