1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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);
|