]> git.ipfire.org Git - thirdparty/u-boot.git/blame - test/compression.c
cmd: setexpr: fix no matching string in gsub return empty value
[thirdparty/u-boot.git] / test / compression.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
3153e915
KC
2/*
3 * Copyright (c) 2013, The Chromium Authors
3153e915
KC
4 */
5
3153e915 6#include <common.h>
65d373ab 7#include <abuf.h>
6ed4dc78 8#include <bootm.h>
3153e915 9#include <command.h>
0c670fc1 10#include <gzip.h>
4d72caa5 11#include <image.h>
f7ae49fc 12#include <log.h>
3153e915 13#include <malloc.h>
0eb25b61 14#include <mapmem.h>
6ed4dc78 15#include <asm/io.h>
3153e915 16
2a2d8e94 17#include <u-boot/lz4.h>
3153e915
KC
18#include <u-boot/zlib.h>
19#include <bzlib.h>
20
21#include <lzma/LzmaTypes.h>
22#include <lzma/LzmaDec.h>
23#include <lzma/LzmaTools.h>
24
25#include <linux/lzo.h>
65d373ab 26#include <linux/zstd.h>
0aac10f2
SG
27#include <test/compression.h>
28#include <test/suites.h>
29#include <test/ut.h>
3153e915
KC
30
31static const char plain[] =
32 "I am a highly compressable bit of text.\n"
33 "I am a highly compressable bit of text.\n"
34 "I am a highly compressable bit of text.\n"
35 "There are many like me, but this one is mine.\n"
36 "If I were any shorter, there wouldn't be much sense in\n"
37 "compressing me in the first place. At least with lzo, anyway,\n"
38 "which appears to behave poorly in the face of short text\n"
39 "messages.\n";
40
41/* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
42static const char bzip2_compressed[] =
43 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
44 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
45 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
46 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
47 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
48 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
49 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
50 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
51 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
52 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
53 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
54 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
55 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
56 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
57 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
093e8c8d 58static const unsigned long bzip2_compressed_size = sizeof(bzip2_compressed) - 1;
3153e915
KC
59
60/* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
61static const char lzma_compressed[] =
62 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
63 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
64 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
65 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
66 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
67 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
68 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
69 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
70 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
71 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
72 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
73 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
74 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
75 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
76 "\xfd\xf5\x50\x8d\xca";
093e8c8d 77static const unsigned long lzma_compressed_size = sizeof(lzma_compressed) - 1;
3153e915
KC
78
79/* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
80static const char lzo_compressed[] =
81 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
82 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
83 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
84 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
85 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
86 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
87 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
88 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
89 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
90 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
91 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
92 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
93 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
94 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
95 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
96 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
97 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
98 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
99 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
100 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
101 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
093e8c8d 102static const unsigned long lzo_compressed_size = sizeof(lzo_compressed) - 1;
3153e915 103
027b728d
JW
104/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
105static const char lz4_compressed[] =
106 "\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
107 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
108 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
109 "\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
110 "\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
111 "\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
112 "\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
113 "\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
114 "\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
115 "\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
116 "\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
117 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
118 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
119 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
120 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
121 "\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
122 "\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
123 "\x9d\x12\x8c\x9d";
093e8c8d 124static const unsigned long lz4_compressed_size = sizeof(lz4_compressed) - 1;
027b728d 125
65d373ab
BM
126/* zstd -19 -c /tmp/plain.txt > /tmp/plain.zst */
127static const char zstd_compressed[] =
128 "\x28\xb5\x2f\xfd\x64\x5e\x00\xbd\x05\x00\x02\x0e\x26\x1a\x70\x17"
129 "\xb8\x0d\x0c\x53\x5c\x9d\x97\xee\xa0\x5d\x84\x89\x3f\x5c\x7a\x78"
130 "\x00\x80\x80\x0f\xe8\xdf\xaf\x06\x66\xd0\x23\xa6\x7a\x64\x8e\xf4"
131 "\x0d\x5b\x47\x65\x26\x7e\x81\xdd\x0b\xe7\x5a\x95\x3d\x49\xcc\x67"
132 "\xe0\x2d\x46\x58\xb6\xac\x64\x16\xf2\xe0\xf8\x16\x17\xaf\xda\x8f"
133 "\x37\xc0\xc3\x0d\x3b\x89\x57\x15\x1e\x46\x46\x12\x9a\x84\xbe\xa6"
134 "\xab\xcf\x50\x90\x5f\x78\x01\xd2\xc0\x51\x72\x59\x0b\xea\xab\xf2"
135 "\xd4\x2b\x2d\x26\x7c\x10\x66\x78\x42\x64\x45\x3f\xa5\x15\x6f\xbd"
136 "\x4a\x61\xe1\xc8\x27\xc0\xe3\x95\x0c\xf9\xca\x7c\xf5\x13\x30\xc3"
137 "\x1a\x7c\x7d\xa4\x17\x0b\xff\x14\xa6\x7a\x95\xa0\x34\xbc\xce\x21"
138 "\x78\x36\x23\x33\x11\x09\x00\x60\x13\x00\x63\xa3\x8e\x28\x94\x55"
139 "\x15\xb6\x26\x68\x05\x4f\x23\x12\xee\x53\x55\x2d\x44\x2f\x54\x95"
140 "\x01\xe4\xf4\x6e\xfa";
141static const unsigned long zstd_compressed_size = sizeof(zstd_compressed) - 1;
142
3153e915
KC
143
144#define TEST_BUFFER_SIZE 512
145
0aac10f2
SG
146typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
147 void *, unsigned long, unsigned long *);
3153e915 148
0aac10f2
SG
149static int compress_using_gzip(struct unit_test_state *uts,
150 void *in, unsigned long in_size,
3153e915
KC
151 void *out, unsigned long out_max,
152 unsigned long *out_size)
153{
154 int ret;
155 unsigned long inout_size = out_max;
156
157 ret = gzip(out, &inout_size, in, in_size);
158 if (out_size)
159 *out_size = inout_size;
160
161 return ret;
162}
163
0aac10f2
SG
164static int uncompress_using_gzip(struct unit_test_state *uts,
165 void *in, unsigned long in_size,
3153e915
KC
166 void *out, unsigned long out_max,
167 unsigned long *out_size)
168{
169 int ret;
170 unsigned long inout_size = in_size;
171
172 ret = gunzip(out, out_max, in, &inout_size);
173 if (out_size)
174 *out_size = inout_size;
175
176 return ret;
177}
178
0aac10f2
SG
179static int compress_using_bzip2(struct unit_test_state *uts,
180 void *in, unsigned long in_size,
93e14596
WD
181 void *out, unsigned long out_max,
182 unsigned long *out_size)
3153e915
KC
183{
184 /* There is no bzip2 compression in u-boot, so fake it. */
0aac10f2 185 ut_asserteq(in_size, strlen(plain));
f91f366b 186 ut_asserteq_mem(plain, in, in_size);
3153e915
KC
187
188 if (bzip2_compressed_size > out_max)
189 return -1;
190
191 memcpy(out, bzip2_compressed, bzip2_compressed_size);
192 if (out_size)
193 *out_size = bzip2_compressed_size;
194
195 return 0;
196}
197
0aac10f2
SG
198static int uncompress_using_bzip2(struct unit_test_state *uts,
199 void *in, unsigned long in_size,
3153e915
KC
200 void *out, unsigned long out_max,
201 unsigned long *out_size)
202{
203 int ret;
204 unsigned int inout_size = out_max;
205
206 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
207 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
208 if (out_size)
209 *out_size = inout_size;
210
211 return (ret != BZ_OK);
212}
213
0aac10f2
SG
214static int compress_using_lzma(struct unit_test_state *uts,
215 void *in, unsigned long in_size,
3153e915
KC
216 void *out, unsigned long out_max,
217 unsigned long *out_size)
218{
219 /* There is no lzma compression in u-boot, so fake it. */
0aac10f2 220 ut_asserteq(in_size, strlen(plain));
f91f366b 221 ut_asserteq_mem(plain, in, in_size);
3153e915
KC
222
223 if (lzma_compressed_size > out_max)
224 return -1;
225
226 memcpy(out, lzma_compressed, lzma_compressed_size);
227 if (out_size)
228 *out_size = lzma_compressed_size;
229
230 return 0;
231}
232
0aac10f2
SG
233static int uncompress_using_lzma(struct unit_test_state *uts,
234 void *in, unsigned long in_size,
3153e915
KC
235 void *out, unsigned long out_max,
236 unsigned long *out_size)
237{
238 int ret;
239 SizeT inout_size = out_max;
240
241 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
242 if (out_size)
243 *out_size = inout_size;
244
245 return (ret != SZ_OK);
246}
247
0aac10f2
SG
248static int compress_using_lzo(struct unit_test_state *uts,
249 void *in, unsigned long in_size,
3153e915
KC
250 void *out, unsigned long out_max,
251 unsigned long *out_size)
252{
253 /* There is no lzo compression in u-boot, so fake it. */
0aac10f2 254 ut_asserteq(in_size, strlen(plain));
f91f366b 255 ut_asserteq_mem(plain, in, in_size);
3153e915
KC
256
257 if (lzo_compressed_size > out_max)
258 return -1;
259
260 memcpy(out, lzo_compressed, lzo_compressed_size);
261 if (out_size)
262 *out_size = lzo_compressed_size;
263
264 return 0;
265}
266
0aac10f2
SG
267static int uncompress_using_lzo(struct unit_test_state *uts,
268 void *in, unsigned long in_size,
3153e915
KC
269 void *out, unsigned long out_max,
270 unsigned long *out_size)
271{
272 int ret;
273 size_t input_size = in_size;
274 size_t output_size = out_max;
275
276 ret = lzop_decompress(in, input_size, out, &output_size);
277 if (out_size)
278 *out_size = output_size;
279
280 return (ret != LZO_E_OK);
281}
282
0aac10f2
SG
283static int compress_using_lz4(struct unit_test_state *uts,
284 void *in, unsigned long in_size,
027b728d
JW
285 void *out, unsigned long out_max,
286 unsigned long *out_size)
287{
288 /* There is no lz4 compression in u-boot, so fake it. */
0aac10f2 289 ut_asserteq(in_size, strlen(plain));
f91f366b 290 ut_asserteq_mem(plain, in, in_size);
027b728d
JW
291
292 if (lz4_compressed_size > out_max)
293 return -1;
294
295 memcpy(out, lz4_compressed, lz4_compressed_size);
296 if (out_size)
297 *out_size = lz4_compressed_size;
298
299 return 0;
300}
301
0aac10f2
SG
302static int uncompress_using_lz4(struct unit_test_state *uts,
303 void *in, unsigned long in_size,
027b728d
JW
304 void *out, unsigned long out_max,
305 unsigned long *out_size)
306{
307 int ret;
308 size_t input_size = in_size;
309 size_t output_size = out_max;
310
311 ret = ulz4fn(in, input_size, out, &output_size);
312 if (out_size)
313 *out_size = output_size;
314
315 return (ret != 0);
316}
317
65d373ab
BM
318static int compress_using_zstd(struct unit_test_state *uts,
319 void *in, unsigned long in_size,
320 void *out, unsigned long out_max,
321 unsigned long *out_size)
322{
323 /* There is no zstd compression in u-boot, so fake it. */
324 ut_asserteq(in_size, strlen(plain));
325 ut_asserteq_mem(plain, in, in_size);
326
327 if (zstd_compressed_size > out_max)
328 return -1;
329
330 memcpy(out, zstd_compressed, zstd_compressed_size);
331 if (out_size)
332 *out_size = zstd_compressed_size;
333
334 return 0;
335}
336
337static int uncompress_using_zstd(struct unit_test_state *uts,
338 void *in, unsigned long in_size,
339 void *out, unsigned long out_max,
340 unsigned long *out_size)
341{
342 struct abuf in_buf, out_buf;
343 int ret;
344
345 abuf_init_set(&in_buf, in, in_size);
346 abuf_init_set(&out_buf, out, out_max);
347
348 ret = zstd_decompress(&in_buf, &out_buf);
349 if (ret >= 0) {
350 *out_size = ret;
351 ret = 0;
352 }
353
354 return ret;
355}
356
3153e915
KC
357#define errcheck(statement) if (!(statement)) { \
358 fprintf(stderr, "\tFailed: %s\n", #statement); \
359 ret = 1; \
360 goto out; \
361}
362
49f22c38
SG
363struct buf_state {
364 ulong orig_size;
365 ulong compressed_size;
366 ulong uncompressed_size;
3153e915 367 void *orig_buf;
49f22c38
SG
368 void *compressed_buf;
369 void *uncompressed_buf;
370 void *compare_buf;
371};
372
0aac10f2 373static int run_test_internal(struct unit_test_state *uts, char *name,
49f22c38
SG
374 mutate_func compress, mutate_func uncompress,
375 struct buf_state *buf)
376{
3153e915
KC
377 int ret;
378
3153e915 379 /* Compress works as expected. */
49f22c38
SG
380 printf("\torig_size:%lu\n", buf->orig_size);
381 memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
bde4c49c 382 ut_assertok(compress(uts, buf->orig_buf, buf->orig_size,
0aac10f2 383 buf->compressed_buf, buf->compressed_size,
bde4c49c 384 &buf->compressed_size));
49f22c38 385 printf("\tcompressed_size:%lu\n", buf->compressed_size);
bde4c49c
BM
386 ut_assert(buf->compressed_size > 0);
387 ut_assert(buf->compressed_size < buf->orig_size);
388 ut_assert(((char *)buf->compressed_buf)[buf->compressed_size - 1]
389 != 'A');
390 ut_asserteq(((char *)buf->compressed_buf)[buf->compressed_size], 'A');
3153e915
KC
391
392 /* Uncompresses with space remaining. */
bde4c49c 393 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
49f22c38 394 buf->uncompressed_buf, buf->uncompressed_size,
bde4c49c 395 &buf->uncompressed_size));
49f22c38 396 printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
bde4c49c
BM
397 ut_asserteq(buf->uncompressed_size, buf->orig_size);
398 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
3153e915
KC
399
400 /* Uncompresses with exactly the right size output buffer. */
49f22c38 401 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
bde4c49c 402 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size,
49f22c38 403 buf->uncompressed_buf, buf->orig_size,
bde4c49c
BM
404 &buf->uncompressed_size));
405 ut_asserteq(buf->uncompressed_size, buf->orig_size);
406 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
407 ut_asserteq(((char *)buf->uncompressed_buf)[buf->orig_size], 'A');
3153e915 408
43b05988
BM
409 /* Uncompresses with trailing garbage in input buffer. */
410 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
bde4c49c 411 ut_assertok(uncompress(uts, buf->compressed_buf, buf->compressed_size + 4,
43b05988 412 buf->uncompressed_buf, buf->uncompressed_size,
bde4c49c
BM
413 &buf->uncompressed_size));
414 ut_asserteq(buf->uncompressed_size, buf->orig_size);
415 ut_asserteq_mem(buf->orig_buf, buf->uncompressed_buf, buf->orig_size);
43b05988 416
3153e915 417 /* Make sure compression does not over-run. */
49f22c38 418 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
0aac10f2 419 ret = compress(uts, buf->orig_buf, buf->orig_size,
49f22c38 420 buf->compare_buf, buf->compressed_size - 1,
3153e915 421 NULL);
bde4c49c
BM
422 ut_asserteq(((char *)buf->compare_buf)[buf->compressed_size], 'A');
423 ut_assert(ret != 0);
3153e915
KC
424 printf("\tcompress does not overrun\n");
425
426 /* Make sure decompression does not over-run. */
49f22c38 427 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
0aac10f2 428 ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
49f22c38 429 buf->compare_buf, buf->uncompressed_size - 1,
3153e915 430 NULL);
bde4c49c
BM
431 ut_asserteq(((char *)buf->compare_buf)[buf->uncompressed_size - 1], 'A');
432 ut_assert(ret != 0);
3153e915
KC
433 printf("\tuncompress does not overrun\n");
434
435 /* Got here, everything is fine. */
bde4c49c 436 return 0;
49f22c38
SG
437}
438
0aac10f2
SG
439static int run_test(struct unit_test_state *uts, char *name,
440 mutate_func compress, mutate_func uncompress)
49f22c38
SG
441{
442 struct buf_state sbuf, *buf = &sbuf;
443 int ret;
444
445 printf(" testing %s ...\n", name);
446
447 buf->orig_buf = (void *)plain;
448 buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
449 errcheck(buf->orig_size > 0);
450
451 buf->compressed_size = TEST_BUFFER_SIZE;
452 buf->uncompressed_size = TEST_BUFFER_SIZE;
453 buf->compressed_buf = malloc(buf->compressed_size);
454 errcheck(buf->compressed_buf);
455 buf->uncompressed_buf = malloc(buf->uncompressed_size);
456 errcheck(buf->uncompressed_buf);
457 buf->compare_buf = malloc(buf->uncompressed_size);
458 errcheck(buf->compare_buf);
459
0aac10f2 460 ret = run_test_internal(uts, name, compress, uncompress, buf);
3153e915
KC
461out:
462 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
463
49f22c38
SG
464 free(buf->compare_buf);
465 free(buf->uncompressed_buf);
466 free(buf->compressed_buf);
3153e915
KC
467
468 return ret;
469}
470
0aac10f2 471static int compression_test_gzip(struct unit_test_state *uts)
3153e915 472{
0aac10f2
SG
473 return run_test(uts, "gzip", compress_using_gzip,
474 uncompress_using_gzip);
475}
476COMPRESSION_TEST(compression_test_gzip, 0);
3153e915 477
0aac10f2
SG
478static int compression_test_bzip2(struct unit_test_state *uts)
479{
480 return run_test(uts, "bzip2", compress_using_bzip2,
481 uncompress_using_bzip2);
482}
483COMPRESSION_TEST(compression_test_bzip2, 0);
484
485static int compression_test_lzma(struct unit_test_state *uts)
486{
487 return run_test(uts, "lzma", compress_using_lzma,
488 uncompress_using_lzma);
489}
490COMPRESSION_TEST(compression_test_lzma, 0);
3153e915 491
0aac10f2
SG
492static int compression_test_lzo(struct unit_test_state *uts)
493{
494 return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
495}
496COMPRESSION_TEST(compression_test_lzo, 0);
3153e915 497
0aac10f2
SG
498static int compression_test_lz4(struct unit_test_state *uts)
499{
500 return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
3153e915 501}
0aac10f2 502COMPRESSION_TEST(compression_test_lz4, 0);
3153e915 503
65d373ab
BM
504static int compression_test_zstd(struct unit_test_state *uts)
505{
506 return run_test(uts, "zstd", compress_using_zstd,
507 uncompress_using_zstd);
508}
509COMPRESSION_TEST(compression_test_zstd, 0);
510
0aac10f2
SG
511static int compress_using_none(struct unit_test_state *uts,
512 void *in, unsigned long in_size,
6ed4dc78
SG
513 void *out, unsigned long out_max,
514 unsigned long *out_size)
515{
516 /* Here we just copy */
517 memcpy(out, in, in_size);
518 *out_size = in_size;
519
520 return 0;
521}
522
523/**
6cc8e545 524 * run_bootm_test() - Run tests on the bootm decompression function
6ed4dc78
SG
525 *
526 * @comp_type: Compression type to test
527 * @compress: Our function to compress data
185f812c 528 * Return: 0 if OK, non-zero on failure
6ed4dc78 529 */
0aac10f2
SG
530static int run_bootm_test(struct unit_test_state *uts, int comp_type,
531 mutate_func compress)
6ed4dc78
SG
532{
533 ulong compress_size = 1024;
534 void *compress_buff;
535 int unc_len;
536 int err = 0;
537 const ulong image_start = 0;
538 const ulong load_addr = 0x1000;
539 ulong load_end;
540
541 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
542 compress_buff = map_sysmem(image_start, 0);
543 unc_len = strlen(plain);
0aac10f2 544 compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
6ed4dc78 545 &compress_size);
2090854c
JW
546 err = image_decomp(comp_type, load_addr, image_start,
547 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
548 compress_buff, compress_size, unc_len,
549 &load_end);
0aac10f2 550 ut_assertok(err);
2090854c
JW
551 err = image_decomp(comp_type, load_addr, image_start,
552 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
553 compress_buff, compress_size, unc_len - 1,
554 &load_end);
0aac10f2 555 ut_assert(err);
6ed4dc78
SG
556
557 /* We can't detect corruption when not decompressing */
558 if (comp_type == IH_COMP_NONE)
559 return 0;
560 memset(compress_buff + compress_size / 2, '\x49',
561 compress_size / 2);
2090854c
JW
562 err = image_decomp(comp_type, load_addr, image_start,
563 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
564 compress_buff, compress_size, 0x10000,
565 &load_end);
0aac10f2 566 ut_assert(err);
6ed4dc78
SG
567
568 return 0;
569}
570
0aac10f2 571static int compression_test_bootm_gzip(struct unit_test_state *uts)
6ed4dc78 572{
0aac10f2
SG
573 return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
574}
575COMPRESSION_TEST(compression_test_bootm_gzip, 0);
6ed4dc78 576
0aac10f2
SG
577static int compression_test_bootm_bzip2(struct unit_test_state *uts)
578{
579 return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
580}
581COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
6ed4dc78 582
0aac10f2
SG
583static int compression_test_bootm_lzma(struct unit_test_state *uts)
584{
585 return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
586}
587COMPRESSION_TEST(compression_test_bootm_lzma, 0);
6ed4dc78 588
0aac10f2
SG
589static int compression_test_bootm_lzo(struct unit_test_state *uts)
590{
591 return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
6ed4dc78 592}
0aac10f2 593COMPRESSION_TEST(compression_test_bootm_lzo, 0);
6ed4dc78 594
0aac10f2
SG
595static int compression_test_bootm_lz4(struct unit_test_state *uts)
596{
597 return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
598}
599COMPRESSION_TEST(compression_test_bootm_lz4, 0);
6ed4dc78 600
65d373ab
BM
601static int compression_test_bootm_zstd(struct unit_test_state *uts)
602{
603 return run_bootm_test(uts, IH_COMP_ZSTD, compress_using_zstd);
604}
605COMPRESSION_TEST(compression_test_bootm_zstd, 0);
606
0aac10f2
SG
607static int compression_test_bootm_none(struct unit_test_state *uts)
608{
609 return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
610}
611COMPRESSION_TEST(compression_test_bootm_none, 0);
612
09140113
SG
613int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc,
614 char *const argv[])
0aac10f2 615{
a7a98755
SG
616 struct unit_test *tests = UNIT_TEST_SUITE_START(compression_test);
617 const int n_ents = UNIT_TEST_SUITE_COUNT(compression_test);
0aac10f2 618
4ad4edfe
PR
619 return cmd_ut_category("compression", "compression_test_",
620 tests, n_ents, argc, argv);
0aac10f2 621}